From 6e70be4f54f3482801d579407846810926cd9997 Mon Sep 17 00:00:00 2001 From: ulrich <undisclosed> Date: Fri, 31 Mar 2017 06:16:56 +0000 Subject: [PATCH] wbx-lib ausgebaut --- src/java/de/uhilger/filecms/web/Initialiser.java | 101 ++++++++++ src/java/de/uhilger/filecms/web/UploadServlet.java | 3 src/java/de/uhilger/filecms/data/FileRef.java | 206 ++++++++++++++++++++ src/java/de/uhilger/filecms/data/Bild.java | 181 ++++++++++++++++++ src/java/de/uhilger/filecms/api/FileMgr.java | 4 src/java/de/uhilger/filecms/api/Api.java | 88 ++++++++ 6 files changed, 576 insertions(+), 7 deletions(-) diff --git a/src/java/de/uhilger/filecms/api/Api.java b/src/java/de/uhilger/filecms/api/Api.java index e9c8a4f..c29311b 100644 --- a/src/java/de/uhilger/filecms/api/Api.java +++ b/src/java/de/uhilger/filecms/api/Api.java @@ -20,19 +20,25 @@ package de.uhilger.filecms.api; +import de.uhilger.filecms.data.FileRef; +import de.uhilger.filecms.web.Initialiser; +import de.uhilger.transit.web.RequestKontext; import de.uhilger.transit.web.WebKontext; -import de.uhilger.wbx.api.ApiBase; -import de.uhilger.wbx.data.FileRef; import java.io.File; +import java.security.Principal; import java.util.logging.Logger; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; /** * */ -public abstract class Api extends ApiBase implements WebKontext { +public abstract class Api implements WebKontext, RequestKontext { protected ServletContext ctx; + + /** Zeiger zum Request, der zur Ausfuehrung fuehrte */ + protected HttpServletRequest request; private static final Logger logger = Logger.getLogger(Api.class.getName()); @@ -107,6 +113,70 @@ } return base; } + + /* -------------- Hilfsfunktionen --------------- */ + + /** + * Das Datenverzeichnis der WebBox ermitteln + * @return Ordner $wbx/daten + */ + protected File getFileBase(ServletContext ctx) { + File file = null; + Object o = ctx.getAttribute(Initialiser.FILE_BASE); + if(o instanceof String) { + String baseStr = (String) o; + logger.fine(baseStr); + file = new File(baseStr); + } + return file; + } + + /** + * Den absoluten Pfad zum Verzeichnis ermitteln das gemaess der + * Tomcat-Doku als CATALINA_BASE der WebBox gilt + * @return absoluter Pfad zu $wbx/sys/base + */ + protected String getCatalinaBase(ServletContext ctx) { + String path = ctx.getRealPath("/"); + logger.fine("getRealPath: " + path); // file-cms in webapps + File file = new File(path); + file = file.getParentFile().getParentFile(); + return file.getAbsolutePath(); + } + + /** + * Den absoluten Pfad zum Datenverzeichnis der WebBox ermitteln + * @return absoluter Pfad zu $wbx/daten + */ + protected String getWbxDataDir(ServletContext ctx) { + return getFileBase(ctx).getAbsolutePath(); + } + + /** + * Das Verzeichnis ermitteln, in dem die WebBox laeuft + * @return der Ordner $wbx + */ + protected File getWbxDir(ServletContext ctx) { + String path = ctx.getRealPath("/"); + logger.fine("getRealPath: " + path); + File file = new File(path); + file = file.getParentFile().getParentFile().getParentFile().getParentFile(); + logger.fine("WebBox: " + file.getAbsolutePath()); + return file; + } + + /** + * den Namen des angemeldeten Benutzers ermitteln + * @return Name des angemeldeten Benutzers oder null, wenn keiner angemeldet ist + */ + protected String getUserName() { + String userName = null; + Object p = getRequest().getUserPrincipal(); + if(p instanceof Principal) { + userName = ((Principal) p).getName(); + } + return userName; + } /* ------------- Implementierung WebKontext ------------- */ @@ -121,4 +191,16 @@ this.ctx = servletContext; } + /* ------------- Implementierung RequestKontext ------------- */ + + @Override + public HttpServletRequest getRequest() { + return request; + } + + @Override + public void setRequest(HttpServletRequest r) { + this.request = r; + } + } diff --git a/src/java/de/uhilger/filecms/api/FileMgr.java b/src/java/de/uhilger/filecms/api/FileMgr.java index 3836e69..3e9151e 100644 --- a/src/java/de/uhilger/filecms/api/FileMgr.java +++ b/src/java/de/uhilger/filecms/api/FileMgr.java @@ -18,8 +18,8 @@ package de.uhilger.filecms.api; -import de.uhilger.wbx.Bild; -import de.uhilger.wbx.data.FileRef; +import de.uhilger.filecms.data.Bild; +import de.uhilger.filecms.data.FileRef; import java.awt.Container; import java.awt.Image; import java.awt.MediaTracker; diff --git a/src/java/de/uhilger/filecms/data/Bild.java b/src/java/de/uhilger/filecms/data/Bild.java new file mode 100644 index 0000000..50b5eb3 --- /dev/null +++ b/src/java/de/uhilger/filecms/data/Bild.java @@ -0,0 +1,181 @@ +/* + Dateiverwaltung - File management in your browser + Copyright (C) 2017 Ulrich Hilger, http://uhilger.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +package de.uhilger.filecms.data; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.awt.image.ConvolveOp; +import java.awt.image.Kernel; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.net.FileNameMap; +import java.net.URLConnection; +import javax.imageio.ImageIO; + +/** + * Methoden zur Verkleinerung von Bildern + */ +public class Bild { + + public static final int WINZIG = 0; + public static final int KLEIN = 1; + public static final int MITTEL = 2; + public static final int GROSS = 3; + + public static final String[] GRNAME = {"-w", "-k", "-m", "-g"}; + public static final int[] GR = {120, 240, 700, 1200}; + + public void writeImageStream(Image image, int gr, String mimeType, OutputStream out) throws InterruptedException, IOException { + ImageIO.write(getReducedImage(image, gr, mimeType), imgType(mimeType), out); + } + + /** + * + * @param image + * @param gr + * @param mimeType + * @param vName Name der verkleinerten Datei + * @throws InterruptedException + * @throws IOException + */ + public void writeImageFile(Image image, int gr, String mimeType, String vName) throws InterruptedException, IOException { + ImageIO.write(getReducedImage(image, gr, mimeType), imgType(mimeType), new File(vName)); + } + + private BufferedImage getReducedImage(Image image, int gr, String mimeType) throws InterruptedException, IOException { + BufferedImage img; + int q = 90; + float sh = 0.f; + if(mimeType.contains("jpeg")) { + img = getReducedImage(image, gr, gr, q, sh, false); + } else { + img = getReducedImage(image, gr, gr, q, sh, true); + } + return img; + } + + /** + * Eine in Groesse und Qualitaet verringerte Bilddatei erzeugen + * @param image Ablageort und Name der Bilddatei + * @param width neue Breite + * @param height neue hoehe + * @param quality neue Qualitaet (0 - 100) + * @param factor Faktor fuer Schaerfe / Unschaerfe (z.B. -0.15f fuer leichte Unschaerfe, 0.05f fuer leichtes Nachschaerfen) + * @param withTransparency ob Transparenz benoetigt wird + * @return neues, in Groesse und Qualitaet entsprechend verringertes Bild + * @throws java.lang.InterruptedException + * @throws java.io.FileNotFoundException + */ + public BufferedImage getReducedImage(Image image, int width, int height, int quality, float factor, boolean withTransparency) + throws InterruptedException, FileNotFoundException, IOException { + + int imageWidth = image.getWidth(null); + int imageHeight = image.getHeight(null); + + int thumbWidth = width; + int thumbHeight = height; + if(imageWidth < width) { + thumbWidth = imageWidth; + } + if(imageHeight < height) { + thumbHeight = imageHeight; + } + double thumbRatio = (double)thumbWidth / (double)thumbHeight; + double imageRatio = (double)imageWidth / (double)imageHeight; + if (thumbRatio < imageRatio) { + thumbHeight = (int)(thumbWidth / imageRatio); + } + else { + thumbWidth = (int)(thumbHeight * imageRatio); + } + + // draw original image to thumbnail image object and + // scale it to the new size on-the-fly + //BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); + BufferedImage thumbImage; + if(withTransparency) { + thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_ARGB); + } else { + thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); + } + Graphics2D graphics2D = thumbImage.createGraphics(); + graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null); + + // 30.7.2007: sharpening hinzugefuegt (Anfang) + //float factor = -0.15f; // minus = sharpen, plus = soften + //float[] sharpenArray = {0, -1, 0, -1, 5, -1, 0, -1, 0}; + + /* + 30.6.2013: sharpening als Weichmacher nur, wenn Bild < 400 + */ + /*if(thumbWidth < 400 || thumbHeight < 400) { + factor = 0.1f; + }*/ + + if(factor != 0.f) { + float[] array = {0, factor, 0, factor, 1-(factor*4), factor, 0, factor, 0}; + Kernel kernel = new Kernel(3, 3, array); + ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); + thumbImage = cOp.filter(thumbImage, null); + } + // 30.7.2007: sharpening hinzugefuegt (Ende) + + return thumbImage; + } + + public String imgType(String mimeType) { + String imgType; + if(mimeType.contains("jpg")) { + imgType = "jpg"; + } else if(mimeType.contains("jpeg")) { + imgType = "jpg"; + } else if(mimeType.contains("png")) { + imgType = "png"; + } else if(mimeType.contains("gif")) { + imgType = "gif"; + } else { + imgType = "jpg"; + } + return imgType; + } + + /** + * + * @param v Bild.WINZIG .. Bild.GROSS + * @return Länge der längsten Kante in Bildpunkten + */ + public int getVariantenGroesse(int v) { + return GR[v]; + } + + public String getVariantenName(int v) { + return GRNAME[v]; + } + + public String getMimeType(File file) { + String absName = file.getAbsolutePath(); + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + return fileNameMap.getContentTypeFor("file://" + absName); + } +} diff --git a/src/java/de/uhilger/filecms/data/FileRef.java b/src/java/de/uhilger/filecms/data/FileRef.java new file mode 100644 index 0000000..22bbe3e --- /dev/null +++ b/src/java/de/uhilger/filecms/data/FileRef.java @@ -0,0 +1,206 @@ +/* + WebBox - Dein Server. + Copyright (C) 2017 Ulrich Hilger, http://uhilger.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.uhilger.filecms.data; + +import java.io.Serializable; + +/** + * A reference to a file consisting of the file's absolute path and additional + * information about whether or not the referenced file is a directory, is hidden, etc. + * Note that FileRef only references a file, the file itself and its contents are not + * modelled by this class. + * + * @author Ulrich Hilger, http://uhilger.de + * @author Bereitgestellt unter den Bedingungen der + * <a href="http://www.gnu.org/licenses/agpl-3.0" target="_blank">GNU Affero + * General Public License</a> + * + * @version 2, 12.01.2008 + */ +public class FileRef implements Serializable { + + public static final long serialVersionUID = 42L; + private String absolutePath; + private Boolean isDirectory; + private Boolean isHidden; + private Long lastModified; + private Long length; + private String mimetype; + + /** + * create a new instance of <code>FileRef</code>. Note that the created FileRef is + * only a reference to a file, the file itself will not be created. + * + * @param absolutePath the absolute path that denotes this instance of <code>FileRef</code> + * @param isDirectory whether or not this file is a directory + * @param isHidden whether or not this file is a hidden file + * @param lastModified the date/time this file was last modified measured in milliseconds + * since the epoch (00:00:00 GMT, January 1, 1970) + * @param length the length of this file in bytes + */ + public FileRef(String absolutePath, boolean isDirectory, boolean isHidden, + long lastModified, long length) + { + super(); + this.absolutePath = absolutePath; + this.isDirectory = isDirectory; + this.isHidden = isHidden; + this.lastModified = lastModified; + this.length = length; + } + + /** + * Create a new instance of class <code>FileRef</code> with a given absolute path. + * Other characteristics of the file are created with default settings + * (i.e. not a directory, not hidden, unknown modification date + * and length). Note that the created FileRef is only a reference to a file, the file + * itself will not be created. + * + * @param absolutePath the absolute path that denotes this instance + * of <code>FileRef</code> + */ + public FileRef(String absolutePath) { + this(absolutePath, false, false, 0, 0); + } + + /** + * Create a new instance of class <code>FileRef</code> with a given absolute path + * and an indicator whether or not the new FileRef denotes a directory. + * Other characteristics of the file are created with default settings + * (i.e. not hidden, unknown modification date and length). Note that the created + * FileRef is only a reference to a file, the file itself will not be created. + * + * @param absolutePath the absolute path that denotes this instance + * of <code>FileRef</code> + * @param isDirectory true, if the file to create should denote a directory + */ + public FileRef(String absolutePath, boolean isDirectory) { + this(absolutePath, isDirectory, false, 0, 0); + } + + public String getMimetype() { + return mimetype; + } + + public void setMimetype(String mimetype) { + this.mimetype = mimetype; + } + + /** + * get the absolute path that denotes this file + * @return the path + */ + public String getAbsolutePath() { + return absolutePath; + } + + /** + * Tests whether the file denoted by this abstract pathname is a + * directory. + * + * @return <code>true</code> if this file is a directory, + * <code>false</code> otherwise + */ + public boolean isDirectory() { + return isDirectory; + } + + /** + * Tests whether the file denoted by this abstract pathname is a + * file. + * + * @return <code>true</code> if this file is a file, + * <code>false</code> otherwise + */ + public boolean isFile() { + return !isDirectory; + } + + /** + * Tests whether the file denoted by this abstract pathname is a + * hidden file. + * + * @return <code>true</code> if this file is a hidden file, + * <code>false</code> otherwise + */ + public boolean isHidden() { + return isHidden; + } + + /** + * Returns the time that this file was + * last modified. + * + * @return A <code>long</code> value representing the time the file was + * last modified, measured in milliseconds since the epoch + * (00:00:00 GMT, January 1, 1970) + */ + public long getLastModified() { + return lastModified; + } + + /** + * Returns the length of this file. + * The return value is unspecified if this file denotes a directory. + * + * @return The length, in bytes, of this file + */ + public long getLength() { + return length; + } + + /** + * get the name of this file without path + * @param separatorChar the string that is used to separate directories and file names in + * path expressions + * @return the name of this file without path + */ + public String getName(String separatorChar) { + String path = getAbsolutePath(); + String name = path.substring(path.lastIndexOf(separatorChar) + 1); + if(name == null || name.length() < 1) { + name = path; + } + return name; + } + + /** + * get a string representation of this instance of FileRef + * @return the string representation of this FileRef object + */ + public String toString() { + return getAbsolutePath(); + } + + /** + * Indicates whether some object is equal to this instance of class FileRef. Two + * GenericFiles are regarded as equal when their absolute paths are equal case independently. + * + * @param obj the object to compare with this instance of FileRef + * @return true, if obj is equal to this instance of FileRef, false if not + */ + public boolean equals(Object obj) { + boolean isEqual = false; + if(obj != null && obj instanceof FileRef) { + isEqual = ((FileRef) obj).getAbsolutePath().toLowerCase().equals( + this.getAbsolutePath().toLowerCase()); + } + return isEqual; + } +} diff --git a/src/java/de/uhilger/filecms/web/Initialiser.java b/src/java/de/uhilger/filecms/web/Initialiser.java new file mode 100644 index 0000000..ea52033 --- /dev/null +++ b/src/java/de/uhilger/filecms/web/Initialiser.java @@ -0,0 +1,101 @@ +/* + Dateiverwaltung - File management in your browser + Copyright (C) 2017 Ulrich Hilger, http://uhilger.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +package de.uhilger.filecms.web; + +import java.io.File; +import java.util.logging.Logger; +import javax.servlet.ServletContext; + +/** + * Initialisieren der Dateiverwaltung + */ +public class Initialiser { + + private static final Logger logger = Logger.getLogger(Initialiser.class.getName()); + + public static final String FILE_BASE = "filebase"; + public static final String DATENABLAGE = "datenAblage"; + + /** + * Bei der WebBox ist das Datenverzeichnis relativ zum Verzeichnis + * $CATALINA_BASE/webapps untergebracht. + * Die Abfrage ServletContext.getRealPath + * liefert das Verzeichnis des Context dieser Webanwendung, also + * $CATALINA_BASE/webapps/file-cms + * oder + * $WBX/sys/base/webapps/file-cms + * + * Unter Windows z.B. + * C:\Users\fred\Documents\srv\wbx\sys\base\webapps\file-cms + * Unter Linux oder Mac OS z.B. + * /home/fred/srv/wbx/sys/base/webapps/file-cms + * + * Das Datenverzeichis liegt dann auf + * $WBX/daten + * + * Mit dem Verzeichnis des Context dieser Webanwendung ist das + * Datenverzeichnis der WebBox hart kodierbar mit dieser Methode + * + * @return Verzeichnis 'daten' der WebBox + */ + protected File getWbxDataDir(ServletContext ctx) { + File file = getWbxDir(ctx); + file = new File(file, "daten/"); + logger.fine("WebBox Datenbasis: " + file.getAbsolutePath()); + return file; + } + + protected File getWbxDir(ServletContext ctx) { + String path = ctx.getRealPath("/"); + logger.fine("getRealPath: " + path); // file-cms in webapps + File file = new File(path); + file = file.getParentFile().getParentFile().getParentFile().getParentFile(); + logger.fine("WebBox: " + file.getAbsolutePath()); + return file; + } + + /** + * Die Dateiablage wird entweder auf einen absoluten Pfad gesetzt, + * der im Deployment Descriptor hinterlegt werden kann oder, wenn + * dort nichts eingetragen ist, auf den hart kodierten Pfad + * der WebBox. + * + * @param ctx der ServletContext, in den die Angabe eingetragen wird. Dort + * ist anschliessend die Angabe unter Initialiser.FILE_BASE abrufbar + */ + protected void ablageErmitteln(ServletContext ctx) { + Object o = ctx.getInitParameter(DATENABLAGE); + try { + if(o instanceof String) { + String pfad = o.toString(); + if(pfad.trim().length() > 0) { + ctx.setAttribute(FILE_BASE, pfad); + logger.fine("Basis: " + pfad); + } else { + ctx.setAttribute(FILE_BASE, getWbxDataDir(ctx).getAbsolutePath()); + } + } else { + ctx.setAttribute(FILE_BASE, getWbxDataDir(ctx).getAbsolutePath()); + } + } catch(Exception ex) { + ctx.setAttribute(FILE_BASE, getWbxDataDir(ctx).getAbsolutePath()); + } + } + +} diff --git a/src/java/de/uhilger/filecms/web/UploadServlet.java b/src/java/de/uhilger/filecms/web/UploadServlet.java index 94e22ca..e0a761f 100644 --- a/src/java/de/uhilger/filecms/web/UploadServlet.java +++ b/src/java/de/uhilger/filecms/web/UploadServlet.java @@ -22,8 +22,7 @@ import static de.uhilger.filecms.api.FileMgr.HOME_DIR_PATH; import static de.uhilger.filecms.api.FileMgr.PUB_DIR_NAME; import static de.uhilger.filecms.api.FileMgr.PUB_DIR_PATH; -import de.uhilger.wbx.data.FileRef; -import de.uhilger.wbx.web.Initialiser; +import de.uhilger.filecms.data.FileRef; import java.io.File; import java.io.IOException; import java.io.InputStream; -- Gitblit v1.9.3