Java tutorial
/* * * Copyright (C) 2012-2014 R T Huitema. All Rights Reserved. * Web: www.42.co.nz * Email: robert@42.co.nz * Author: R T Huitema * * This file is part of the signalk-server-java project * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * 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 nz.co.fortytwo.signalk.processor; import static nz.co.fortytwo.signalk.util.ConfigConstants.MAP_DIR; import static nz.co.fortytwo.signalk.util.ConfigConstants.STATIC_DIR; import static nz.co.fortytwo.signalk.util.SignalKConstants.dot; import static nz.co.fortytwo.signalk.util.SignalKConstants.name; import static nz.co.fortytwo.signalk.util.SignalKConstants.resources; import static nz.co.fortytwo.signalk.util.SignalKConstants.resources_charts; import static nz.co.fortytwo.signalk.util.SignalKConstants.routes; import static nz.co.fortytwo.signalk.util.SignalKConstants.value; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; import java.util.UUID; import java.util.zip.ZipException; import java.util.zip.ZipFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.component.http.HttpMessage; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.restlet.data.MediaType; import org.restlet.ext.fileupload.RestletFileUpload; import org.restlet.representation.InputRepresentation; import mjson.Json; import nz.co.fortytwo.signalk.util.SignalKConstants; import nz.co.fortytwo.signalk.util.Util; import nz.co.fortytwo.signalk.util.ZipUtils; public class UploadProcessor extends SignalkProcessor implements Processor { private static Logger logger = LogManager.getLogger(UploadProcessor.class); @Override public void process(Exchange exchange) throws Exception { logger.debug("UploadProcessor starts"); HttpServletRequest request = exchange.getIn(HttpMessage.class).getRequest(); logger.debug("Session = " + request.getSession().getId()); HttpSession session = request.getSession(); if (logger.isDebugEnabled()) { logger.debug("Request = " + exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST).getClass()); logger.debug("Session = " + session.getId()); } if (session.getId() != null) { String remoteAddress = request.getRemoteAddr(); String localAddress = request.getLocalAddr(); if (Util.sameNetwork(localAddress, remoteAddress)) { exchange.getIn().setHeader(SignalKConstants.MSG_TYPE, SignalKConstants.INTERNAL_IP); } else { exchange.getIn().setHeader(SignalKConstants.MSG_TYPE, SignalKConstants.EXTERNAL_IP); } if (exchange.getIn().getHeader(Exchange.HTTP_METHOD).equals("POST")) { processUpload(exchange); } } else { exchange.getIn().setHeader("Location", SignalKConstants.SIGNALK_AUTH); exchange.getIn().setBody("Authentication Required"); } } private void processUpload(Exchange exchange) throws Exception { logger.debug("Begin import:" + exchange.getIn().getHeaders()); if (exchange.getIn().getBody() != null) { logger.debug("Body class:" + exchange.getIn().getBody().getClass()); } else { logger.debug("Body class is null"); } //logger.debug("Begin import:"+ exchange.getIn().getBody()); MediaType mediaType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, MediaType.class); InputRepresentation representation = new InputRepresentation((InputStream) exchange.getIn().getBody(), mediaType); logger.debug("Found MIME:" + mediaType + ", length:" + exchange.getIn().getHeader(Exchange.CONTENT_LENGTH, Integer.class)); //make a reply Json reply = Json.read("{\"files\": []}"); Json files = reply.at("files"); try { List<FileItem> items = new RestletFileUpload(new DiskFileItemFactory()) .parseRepresentation(representation); logger.debug("Begin import files:" + items); for (FileItem item : items) { if (!item.isFormField()) { InputStream inputStream = item.getInputStream(); Path destination = Paths.get( Util.getConfigProperty(STATIC_DIR) + Util.getConfigProperty(MAP_DIR) + item.getName()); logger.debug("Save import file:" + destination); long len = Files.copy(inputStream, destination, StandardCopyOption.REPLACE_EXISTING); Json f = Json.object(); f.set("name", item.getName()); f.set("size", len); files.add(f); install(destination); } } } catch (FileUploadException | IOException e) { logger.error(e.getMessage(), e); } exchange.getIn().setBody(reply); } private void install(Path destination) throws Exception { if (!destination.toString().endsWith(".zip")) return; //unzip here logger.debug("Unzipping file:" + destination); try { File zipFile = destination.toFile(); String f = destination.toFile().getName(); f = f.substring(0, f.indexOf(".")); File destDir = new File(Util.getConfigProperty(STATIC_DIR) + Util.getConfigProperty(MAP_DIR) + f); if (!destDir.exists()) { destDir.mkdirs(); } ZipUtils.unzip(destDir, zipFile); logger.debug("Unzipped file:" + destDir); //now add a reference in resources loadChart(f); } catch (Exception e) { logger.error(e.getMessage(), e); throw e; } } public void loadChart(String chartName) throws Exception { try { File destDir = new File( Util.getConfigProperty(STATIC_DIR) + Util.getConfigProperty(MAP_DIR) + chartName); SAXReader reader = new SAXReader(); Document document = reader.read(new File(destDir, "tilemapresource.xml")); String title = document.getRootElement().element("Title").getText(); String scale = "250000"; if (document.getRootElement().element("Metadata") != null) { scale = document.getRootElement().element("Metadata").attribute("scale").getText(); } double maxRes = 0.0; double minRes = Double.MAX_VALUE; int maxZoom = 0; int minZoom = 99; Element tileSets = document.getRootElement().element("TileSets"); for (Object o : tileSets.elements("TileSet")) { Element e = (Element) o; int href = Integer.parseInt(e.attribute("href").getValue()); maxZoom = Math.max(href, maxZoom); minZoom = Math.min(href, minZoom); double units = Double.parseDouble(e.attribute("units-per-pixel").getValue()); maxRes = Math.max(units, maxRes); minRes = Math.min(units, minRes); } //now make an entry in resources Json resource = createChartMsg(chartName, title, scale); inProducer.asyncSendBody(inProducer.getDefaultEndpoint(), resource); } catch (Exception e) { logger.error(e.getMessage(), e); throw e; } } private Json createChartMsg(String f, String title, String scale) { Json val = Json.object(); val.set(SignalKConstants.PATH, "charts." + "urn:mrn:signalk:uuid:" + UUID.randomUUID().toString()); Json currentChart = Json.object(); val.set(value, currentChart); String time = Util.getIsoTimeString(); time = time.substring(0, time.indexOf(".")); currentChart.set("identifier", f); currentChart.set(name, title); currentChart.set("description", title); currentChart.set("tilemapUrl", "/" + Util.getConfigProperty(MAP_DIR) + f); try { int scaleInt = Integer.valueOf(scale); currentChart.set("scale", scaleInt); } catch (Exception e) { currentChart.set("scale", 0); } Json values = Json.array(); values.add(val); Json update = Json.object(); update.set(SignalKConstants.values, values); Json updates = Json.array(); updates.add(update); Json msg = Json.object(); msg.set(SignalKConstants.CONTEXT, resources); msg.set(SignalKConstants.PUT, updates); if (logger.isDebugEnabled()) logger.debug("Created new chart msg:" + msg); return msg; } }