/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.applet.upload; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Insets; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.swing.JApplet; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.filechooser.FileFilter; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.params.HttpMethodParams; /** * File Upload Applet, displays a file selector box to upload multiple resources into OpenCms.<p> * * @since 6.0.0 */ public class FileUploadApplet extends JApplet implements Runnable { /** The JSESSIONID cookie header name. */ public static final String C_JSESSIONID = "JSESSIONID"; /** The value for the resource upload applet action. */ // Warning: This constant has to be kept in sync with the same named constant in // org.opencms.explorer.CmsNewResourceUpload public static final String DIALOG_CHECK_OVERWRITE = "checkoverwrite"; /** Serial version UID required for safe serialization. */ private static final long serialVersionUID = -3710093915699772778L; /** Output string for action messages. */ private String m_action = ""; private String m_actionOutputCount = "Counting resources ...."; private String m_actionOutputCreate = "Creating Zip-File..."; private String m_actionOutputError = "Error"; /** Definition of output strings.*/ private String m_actionOutputSelect = "Seleting files for upload...."; private String m_actionOutputUpload = "Upload Zip-File"; private String m_actionOverwriteCheck = "Checking file existance on server..."; /** Indicates if the applet certificate has been accepted. */ private boolean m_certificateAccepted; private String m_certificateErrorMessage = "The required Applet certificate has not been accepted!"; private String m_certificateErrorTitle = "Error initializing the OpenCms Upload Applet"; /** The initial folder path for the file chooser. */ private String m_clientFolder; /** Color definitions. */ private HashMap m_colors = new HashMap(); private String m_errorLine1 = "An error has occurred on the server:"; /** The URL to return to after an error. */ private String m_errorUrl = ""; /** File extensions, used to find the correct icons for the select box. */ private String m_fileExtensions = ""; /** The type of gallery to upload to. */ private String m_fileFilterSelection = ""; /** The file selector. */ private UploadAppletFileChooser m_fileSelector; private Image m_floater; /** Image position for the floater during upload. */ private int m_floaterPos = 50; /** Definition variables for graphics output. */ private Font m_font; /** Maximum file upload size. */ private long m_maxsize = -1; /** Output string for logging messages. */ private String m_message = ""; private String m_messageNoPreview = "no preview available"; private String m_messageOutputAdding = "Adding "; private String m_messageOutputErrorSize = "Zip file too big:"; private String m_messageOutputErrorZip = "Error creating Zip-File, see Java Console."; private String m_messageOutputUpload = "Please wait, uploading data..."; private FontMetrics m_metrics; private Graphics m_offgraphics; private Image m_offscreen; /** The URL of the OpenCms instance. */ private String m_opencms = ""; /** Output mode selector. */ private int m_outputMode; private ModalDialog m_overwriteDialog; private String m_overwriteDialogCancel = "Cancel"; private String m_overwriteDialogIntro = "The files listed below already exist on the server. \nAll checked files will be overwritten."; private String m_overwriteDialogLocale = "en"; private String m_overwriteDialogOk = "Ok"; private String m_overwriteDialogTitle = "Select the files to overwrite on the server"; /** List of potential overwrites. */ private List m_overwrites; /** The Target Frame to return to after uploading the files. */ private String m_redirectTargetFrame = ""; /** The URL to return to after uploading the files. */ private String m_redirectUrl = ""; /** Number of resources to upload. */ private int m_resources; /** Applet thread. */ private Thread m_runner; /** Definition of the images during upload. */ private Image m_source; /** Counter for creating the progress bar. */ private int m_step; private Image m_target; /** The URL to send the uploaded files to. */ private String m_targetUrl = ""; /** The name of the folder to upload to. */ private String m_uploadFolder = ""; /** * Adds a single file to the zip output.<p> * * @param zipStream the zip output stream * @param file the file to add to the stream * @throws Exception if something goes wrong */ private void addFileToZip(ZipOutputStream zipStream, File file) throws Exception { // add to zipfile String name = file.getAbsolutePath().replace('\\', '/'); name = name.substring(m_fileSelector.getCurrentDirectory().getAbsolutePath().length()); m_message = m_messageOutputAdding + " " + name + ".."; m_step++; repaint(); ZipEntry entry = new ZipEntry(name); zipStream.putNextEntry(entry); writeFileBytes(file, zipStream); zipStream.closeEntry(); } private void addFolderToZip(ZipOutputStream zipStream, File file) throws Exception { File[] children = file.listFiles(); File child; for (int i = 0; i < children.length; i++) { child = children[i]; if (child.isDirectory()) { addFolderToZip(zipStream, child); } else { addFileToZip(zipStream, child); } } } /** * Returns the merge of both file arrays with no check for duplications. <p> * * @param files first array of files * * @param overwriteFiles 2nd array of files * * @return the union of both file arrays */ private File[] addOverwrites(File[] files, File[] overwriteFiles) { List result = new ArrayList(files.length + overwriteFiles.length); // faster for loop;) for (int i = files.length - 1; i >= 0; i--) { result.add(files[i]); } for (int i = overwriteFiles.length - 1; i >= 0; i--) { result.add(overwriteFiles[i]); } return (File[])result.toArray(new File[result.size()]); } /** * Checks if the given client files exist on the server and internally stores duplications.<p> * * Comparison is made by cutting the current directory of the file chooser from the path of the given files. * The server files (VFS files) to compare to are found by the current session of the user which finds the correct site and * the knowledge about the current directory. File translation rules are taken into account on the server. <p> * * @param files the local files to check if they exist in the VFS * * @return one of {@link ModalDialog#ERROR_OPTION} , {@link ModalDialog#CANCEL_OPTION}, {@link ModalDialog#APPROVE_OPTION}. */ int checkServerOverwrites(File[] files) { m_action = m_actionOverwriteCheck; repaint(); int rtv = ModalDialog.ERROR_OPTION; // collect files List fileNames = new ArrayList(); for (int i = 0; i < files.length; i++) { getRelativeFilePaths(files[i], fileNames); } StringBuffer uploadFiles = new StringBuffer(); Iterator it = fileNames.iterator(); // Http post header is limited, therefore only a ceratain amount of files may be checked // for server overwrites. Solution is: multiple requests. int count = 0; List duplications; // request to server HttpClient client = new HttpClient(); this.m_overwrites = new ArrayList(); try { while (it.hasNext()) { count++; uploadFiles.append(((String)it.next())).append('\n'); if (((count % 40) == 0) || (!it.hasNext())) { // files to upload: PostMethod post = new PostMethod(m_targetUrl); Header postHeader = new Header("uploadFiles", URLEncoder.encode(uploadFiles.toString(), "utf-8")); post.addRequestHeader(postHeader); // upload folder in vfs: Header header2 = new Header("uploadFolder", URLEncoder.encode(getParameter("filelist"), "utf-8")); post.addRequestHeader(header2); // the action constant post.setParameter("action", DIALOG_CHECK_OVERWRITE); // add jsessionid query string String sessionId = getParameter("sessionId"); String query = ";" + C_JSESSIONID.toLowerCase() + "=" + sessionId; post.setQueryString(query); post.addRequestHeader(C_JSESSIONID, sessionId); HttpConnectionParams connectionParams = client.getHttpConnectionManager().getParams(); connectionParams.setConnectionTimeout(5000); // add the session cookie client.getState(); client.getHostConfiguration().getHost(); HttpState initialState = new HttpState(); URI uri = new URI(m_targetUrl, false); Cookie sessionCookie = new Cookie(uri.getHost(), C_JSESSIONID, sessionId, "/", null, false); initialState.addCookie(sessionCookie); client.setState(initialState); int status = client.executeMethod(post); if (status == HttpStatus.SC_OK) { String response = post.getResponseBodyAsString(); duplications = parseDuplicateFiles(URLDecoder.decode(response, "utf-8")); this.m_overwrites.addAll(duplications); } else { // continue without overwrite check String error = m_errorLine1 + "\n" + post.getStatusLine(); System.err.println(error); } count = 0; uploadFiles = new StringBuffer(); } } if (m_overwrites.size() > 0) { rtv = showDuplicationsDialog(m_overwrites); } else { rtv = ModalDialog.APPROVE_OPTION; } } catch (HttpException e) { // TODO Auto-generated catch block e.printStackTrace(System.err); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(System.err); } return rtv; } /** * Counts all resources to add to the zip file.<p> * * @param files the files to be packed into the zipfile * @return number of resources */ private int countResources(File[] files) { int count = 0; // look through all selected resources for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { // its a file, count it count++; } else { // its a folder, count all resources in it and add the number count += countSubresources(files[i]); } } return count; } /** * Counts all resources in a folder.<p> * * @param folder the folder to count * @return number of resources */ private int countSubresources(File folder) { int count = 0; if (folder.isFile()) { // check if is really a folder count = 1; } else { // recurse to count count = countResources(folder.listFiles()); } return count; } /** * Creates a ZipFile from all files to upload.<p> * * @param files the files to be packed into the zipfile * @return reference to the zipfile */ private File createZipFile(File[] files) { File targetFile = null; if (files.length > 0) { m_action = m_actionOutputCreate; try { // create a new zipStream String zipFileName = ".opencms_upload.zip"; String userHome = System.getProperty("user.home"); // create file in user home directory where write permissions should exist if (userHome != null) { if (!userHome.endsWith(File.separator)) { userHome = userHome + File.separator; } zipFileName = userHome + zipFileName; } ZipOutputStream zipStream = new ZipOutputStream(new FileOutputStream(zipFileName)); // loop through all files for (int i = 0; i < files.length; i++) { // if its a file, add it to the zipfile if (files[i].isFile()) { addFileToZip(zipStream, files[i]); } else { addFolderToZip(zipStream, files[i]); } repaint(); // free mem files[i] = null; } zipStream.close(); // get the zipfile targetFile = new File(zipFileName); } catch (Exception e) { System.err.println("Error creating zipfile " + getStackTraceAsString(e)); } } return targetFile; } /** * Returns the stack trace (including the message) of an exception as a String.<p> * * If the exception is a CmsException, * also writes the root cause to the String.<p> * * @param e the exception to get the stack trace from * @return the stack trace of an exception as a String */ private static String getStackTraceAsString(Throwable e) { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); e.printStackTrace(printWriter); return stringWriter.toString(); } /** * @see java.applet.Applet#destroy() */ public void destroy() { // NOOP } /** * Displays an error message in case the applet could not be initialized.<p> */ public void displayError() { m_outputMode = 5; m_action = m_certificateErrorTitle; m_message = m_certificateErrorMessage; JOptionPane.showMessageDialog(this, m_message, m_action, JOptionPane.ERROR_MESSAGE); try { // redirect back to the server getAppletContext().showDocument(new URL(m_redirectUrl), m_redirectTargetFrame); } catch (MalformedURLException e) { // this should never happen e.printStackTrace(); } stop(); } /** * Extracts the colors from the parameter String.<p> * * @param colors list of color names and values * @return HashMap with color names and values */ private HashMap extractColors(String colors) { HashMap colorStorage = new HashMap(); if (colors != null) { StringTokenizer tok = new StringTokenizer(colors, ","); // loop through the tokens // all tokens have the format "extension=type" while (tok.hasMoreElements()) { String token = tok.nextToken(); // now extract the file extension and the type String colorName = token.substring(0, token.indexOf("=")); String colorValue = token.substring(token.indexOf("=") + 1); colorStorage.put(colorName, colorValue); } } return colorStorage; } /** * Gets a color for drawing the output.<p> * * @param colorName the name of the color * @return color */ private Color getColor(String colorName) { Color col = Color.black; try { col = Color.decode((String)m_colors.get(colorName)); } catch (Exception e) { System.err.println("Error reading " + colorName + ":" + e); } return col; } /** * Puts all given files (and all files in subtree of given potential "folder" file) into the given * list (as {@link File} instances) with respect to the current file filter in the file chooser. * <p> * * * @param file the file or folder to collect all subfiles of with respect to the current file chooser. * * @param fileNames all given files (and all files in subtree of given potential "folder" file) into the given * list (as {@link File} instances) with respect to the current file filter in the file chooser */ private void getFilesInTree(final File file, final List fileNames) { if (file.isDirectory()) { File[] children = file.listFiles(); for (int i = 0; i < children.length; i++) { getFilesInTree(children[i], fileNames); } } else { FileFilter filter = m_fileSelector.getFileFilter(); if (filter.accept(file)) { fileNames.add(file); } } } /** * Puts the path of the given file in relation to the current root directory of the intenal * file chooser with support for folder-recursion. <p> * * * @param file the file to put into relation to the root directory of the internal file chooser or a folder * of files to do this. * * @param fileNames will contain the result. */ private void getRelativeFilePaths(final File file, final List fileNames) { if (file.isDirectory()) { File[] children = file.listFiles(); for (int i = 0; i < children.length; i++) { getRelativeFilePaths(children[i], fileNames); } } else { FileFilter filter = m_fileSelector.getFileFilter(); if (filter.accept(file)) { String rootDir = m_fileSelector.getCurrentDirectory().getAbsolutePath(); int rootDirLength = rootDir.length(); String filePath = file.getAbsolutePath(); filePath = filePath.substring(rootDirLength); filePath = filePath.replace('\\', '/'); fileNames.add(filePath); } } } /** * @see java.applet.Applet#init() */ public void init() { // has to be first before any gui components are created if (getParameter("overwriteDialogLocale") != null) { m_overwriteDialogLocale = getParameter("overwriteDialogLocale"); Locale wpLocale = new Locale(m_overwriteDialogLocale); setLocale(wpLocale); } m_opencms = getParameter("opencms"); m_targetUrl = getParameter("target"); m_redirectUrl = getParameter("redirect"); m_redirectTargetFrame = getParameter("targetframe"); if ((m_redirectTargetFrame == null) || m_redirectTargetFrame.equals("")) { m_redirectTargetFrame = "explorer_files"; } m_errorUrl = getParameter("error"); m_uploadFolder = getParameter("filelist"); m_fileFilterSelection = getParameter("filefilterselection"); String tmpSize = getParameter("maxsize"); if ((tmpSize != null) && (tmpSize.length() > 0)) { m_maxsize = Long.parseLong(tmpSize); } m_fileExtensions = getParameter("fileExtensions"); m_colors = extractColors(getParameter("colors")); // setup the applet output m_font = new java.awt.Font(null, Font.BOLD, 12); m_metrics = getFontMetrics(m_font); m_source = getImage(getCodeBase(), "org/opencms/applet/upload/applet_source.png"); m_target = getImage(getCodeBase(), "org/opencms/applet/upload/applet_target.png"); m_floater = getImage(getCodeBase(), "org/opencms/applet/upload/floater.gif"); // get the output massages in the correct language if (getParameter("actionOutputSelect") != null) { m_actionOutputSelect = getParameter("actionOutputSelect"); } if (getParameter("actionOutputCount") != null) { m_actionOutputCount = getParameter("actionOutputCount"); } if (getParameter("actionOutputCreate") != null) { m_actionOutputCreate = getParameter("actionOutputCreate"); } if (getParameter("actionOverwriteCheck") != null) { m_actionOverwriteCheck = getParameter("actionOverwriteCheck"); } if (getParameter("actionOutputUpload") != null) { m_actionOutputUpload = getParameter("actionOutputUpload"); } if (getParameter("actionOutputError") != null) { m_actionOutputError = getParameter("actionOutputError"); } if (getParameter("messageOutputUpload") != null) { m_messageOutputUpload = getParameter("messageOutputUpload"); } if (getParameter("messageOutputAdding") != null) { m_messageOutputAdding = getParameter("messageOutputAdding"); } if (getParameter("messageOutputErrorZip") != null) { m_messageOutputErrorZip = getParameter("messageOutputErrorZip"); } if (getParameter("messageOutputErrorSize") != null) { m_messageOutputErrorSize = getParameter("messageOutputErrorSize"); } if (getParameter("messageNoPreview") != null) { m_messageNoPreview = getParameter("messageNoPreview"); } if (getParameter("errorLine1") != null) { m_errorLine1 = getParameter("errorLine1"); } if (getParameter("certificateErrorTitle") != null) { m_certificateErrorTitle = getParameter("certificateErrorTitle"); } if (getParameter("certificateErrorMessage") != null) { m_certificateErrorMessage = getParameter("certificateErrorMessage"); } if (getParameter("overwriteDialogTitle") != null) { m_overwriteDialogTitle = getParameter("overwriteDialogTitle"); } if (getParameter("overwriteDialogIntro") != null) { m_overwriteDialogIntro = getParameter("overwriteDialogIntro"); } if (getParameter("overwriteDialogCancel") != null) { m_overwriteDialogCancel = getParameter("overwriteDialogCancel"); } if (getParameter("overwriteDialogOk") != null) { m_overwriteDialogOk = getParameter("overwriteDialogOk"); } if (getParameter("clientFolder") != null) { m_clientFolder = getParameter("clientFolder"); } m_certificateAccepted = true; try { // set log factory to default log factory, otherwise commons logging detection will fail with an exception System.setProperty( org.apache.commons.logging.LogFactory.FACTORY_PROPERTY, org.apache.commons.logging.LogFactory.FACTORY_DEFAULT); } catch (SecurityException e) { // this indicates the applet certificate has not been accepted m_certificateAccepted = false; e.printStackTrace(); } } /** * Move the floating upload image to right, wrap around on right side.<p> */ public void moveFloater() { m_floaterPos += 10; if ((m_floaterPos) > 430) { m_floaterPos = 50; } repaint(); } /** * @see java.awt.Component#paint(Graphics) */ public void paint(Graphics g) { // create the box m_offscreen = createImage(getSize().width, getSize().height); m_offgraphics = m_offscreen.getGraphics(); m_offgraphics.setColor(getColor("bgColor")); m_offgraphics.fillRect(0, 0, getSize().width, getSize().height); m_offgraphics.setColor(getColor("outerBorderRightBottom")); m_offgraphics.drawLine(0, getSize().height - 1, getSize().width - 1, getSize().height - 1); m_offgraphics.drawLine(getSize().width - 1, 0, getSize().width - 1, getSize().height - 1); m_offgraphics.setColor(getColor("outerBorderLeftTop")); m_offgraphics.drawLine(0, 0, getSize().width - 1, 0); m_offgraphics.drawLine(0, 0, 0, getSize().height - 1); m_offgraphics.setColor(getColor("innerBorderRightBottom")); m_offgraphics.drawLine(1, getSize().height - 2, getSize().width - 2, getSize().height - 2); m_offgraphics.drawLine(getSize().width - 2, 1, getSize().width - 2, getSize().height - 2); m_offgraphics.setColor(getColor("innerBorderLeftTop")); m_offgraphics.drawLine(1, 1, getSize().width - 2, 1); m_offgraphics.drawLine(1, 1, 1, getSize().height - 2); m_offgraphics.setColor(getColor("bgHeadline")); m_offgraphics.fillRect(4, 4, getSize().width - 5, 18); m_offgraphics.setColor(getColor("innerBorderRightBottom")); m_offgraphics.drawLine(10, getSize().height - 11, getSize().width - 11, getSize().height - 11); m_offgraphics.drawLine(getSize().width - 11, 25, getSize().width - 11, getSize().height - 11); m_offgraphics.setColor(getColor("innerBorderLeftTop")); m_offgraphics.drawLine(10, 25, getSize().width - 11, 25); m_offgraphics.drawLine(10, 25, 10, getSize().height - 11); // draw title int cx = 10; int cy = 17; m_offgraphics.setFont(m_font); m_offgraphics.setColor(getColor("colorHeadline")); m_offgraphics.drawString(m_action, cx, cy); m_offgraphics.setColor(getColor("colorText")); // draw process message if (m_outputMode >= 3) { cx = Math.max((getSize().width - m_metrics.stringWidth(m_message)) / 2, 0); } else { cx = 25; } cy = 41; m_offgraphics.drawString(m_message, cx, cy); // draw process bar during zip creation if (m_outputMode == 2) { float bar = new Float(m_step).floatValue() / new Float(m_resources).floatValue(); String barText = "(" + m_step + " / " + m_resources + ")"; m_offgraphics.drawRect(25, 50, 450, 20); m_offgraphics.setColor(Color.white); m_offgraphics.fillRect(26, 51, 449, 19); m_offgraphics.setColor(getColor("progessBar")); m_offgraphics.fillRect(26, 51, new Float(bar * 449).intValue(), 19); int progressWith = m_metrics.stringWidth(barText); cx = Math.max((getSize().width - progressWith) / 2, 0); cy = 64; m_offgraphics.setColor(Color.black); m_offgraphics.drawString(barText, cx, cy); } // show floater during upload if (m_outputMode == 3) { m_offgraphics.drawImage(m_floater, m_floaterPos, 57, this); m_offgraphics.drawImage(m_source, 30, 47, this); m_offgraphics.drawImage(m_target, 440, 47, this); } // copy the offcreen graphics to the applet g.drawImage(m_offscreen, 0, 0, null); } private List parseDuplicateFiles(String responseBodyAsString) { List result = new ArrayList(); LineNumberReader reader = new LineNumberReader(new InputStreamReader(new ByteArrayInputStream( responseBodyAsString.getBytes()))); try { String trim; for (String read = reader.readLine(); read != null; read = reader.readLine()) { trim = read.trim(); if (!(trim.equals("") || trim.equals("\n"))) { // empty strings could happen if the serverside jsp is edited and has new unwanted linebreaks result.add(read); } } } catch (IOException e) { e.printStackTrace(); } return result; } /** * @see java.lang.Runnable#run() */ public void run() { try { boolean ok = true; while (ok) { ok = true; m_message = ""; m_resources = 0; m_step = 0; // create a new file chooser if (m_fileSelector == null) { m_fileSelector = new UploadAppletFileChooser(this); } // file selector can read files and folders m_fileSelector.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); m_fileSelector.setDialogTitle(m_actionOutputSelect); FileFilter imageFilter = new ImageFilter(); FileFilter officeFilter = new OfficeFilter(); FileFilter webFilter = new WebFilter(); // add two custom file filters (office and images) and the default filters m_fileSelector.addChoosableFileFilter(imageFilter); m_fileSelector.addChoosableFileFilter(officeFilter); m_fileSelector.addChoosableFileFilter(webFilter); m_fileSelector.setAcceptAllFileFilterUsed(true); // enable multi-selection of files m_fileSelector.setMultiSelectionEnabled(true); // add custom icons for file types. m_fileSelector.setFileView(new ImageFileView(m_opencms, m_fileExtensions)); // add the image preview pane. m_fileSelector.setAccessory(new ImagePreview(m_fileSelector, m_messageNoPreview)); if ((m_clientFolder != null) && !m_clientFolder.trim().equals("")) { File clientFolder = new File(m_clientFolder); if (clientFolder.exists() && clientFolder.isDirectory()) { m_fileSelector.setCurrentDirectory(clientFolder); } } m_action = m_actionOutputSelect; // pre - selection of the filter: if ((m_fileFilterSelection != null) && !m_fileFilterSelection.trim().equals("")) { if (WebFilter.FILTER_ID.equals(m_fileFilterSelection)) { m_fileSelector.setFileFilter(webFilter); } else if (OfficeFilter.FILTER_ID.equals(m_fileFilterSelection)) { m_fileSelector.setFileFilter(officeFilter); } else if (ImageFilter.FILTER_ID.equals(m_fileFilterSelection)) { m_fileSelector.setFileFilter(imageFilter); } } repaint(); m_overwrites = new ArrayList(); int returnVal = m_fileSelector.showDialog(this, "OK"); // process the results. if (returnVal == JFileChooser.APPROVE_OPTION) { // count all resources m_outputMode = 1; m_action = m_actionOutputCount; repaint(); File[] files = m_fileSelector.getSelectedFiles(); List fileNames = new ArrayList(); for (int i = 0; i < files.length; i++) { getRelativeFilePaths(files[i], fileNames); } if (m_overwrites.size() > 0) { // subtract all duplicate files first files = subtractDuplicates(fileNames, m_overwrites); files = addOverwrites( files, ((FileSelectionPanel)m_overwriteDialog.getControlPanel().getComponent(1)).getSelectedFiles()); } else { fileNames = new ArrayList(); for (int i = 0; i < files.length; i++) { getFilesInTree(files[i], fileNames); } files = (File[])fileNames.toArray(new File[fileNames.size()]); } m_resources = countResources(files); // create the zipfile m_outputMode = 2; if (files.length > 0) { File targetFile = createZipFile(files); // check the size of the zip files if ((targetFile == null) || ((m_maxsize > 0) && (targetFile.length() > m_maxsize))) { // show some details in the applet itself m_outputMode = 4; if (targetFile == null) { m_message = m_messageOutputErrorZip; } else { m_message = m_messageOutputErrorSize + " " + targetFile.length() + " > " + m_maxsize; } m_action = m_actionOutputError; repaint(); // show an error-alertbog JOptionPane.showMessageDialog(this, m_message, m_action, JOptionPane.ERROR_MESSAGE); } else { m_outputMode = 3; m_message = m_messageOutputUpload + " (" + targetFile.length() / 1024 + " kb)"; repaint(); // upload the zipfile FileUploadThread uploadThreat = new FileUploadThread(); uploadThreat.init(this); uploadThreat.start(); uploadZipFile(targetFile); ok = false; } } else { // zero files were selected for upload (might be that all potential overwrites were deselected) ok = false; getAppletContext().showDocument(new URL(m_redirectUrl), m_redirectTargetFrame); } } else { //the cancel button was used, so go back to the workplace ok = false; getAppletContext().showDocument(new URL(m_redirectUrl), m_redirectTargetFrame); } } } catch (RuntimeException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * Displays the dialog that shows the list of files that will be overwritten on the server. * <p> * The user may uncheck the checkboxes in front of the relative paths to avoid overwriting. * <p> * * @param duplications * a list of Strings that are relative paths to the files that will be overwritten on the server * * @return one of */ private int showDuplicationsDialog(List duplications) { int rtv = ModalDialog.ERROR_OPTION; try { JTextArea dialogIntroPanel = new JTextArea(); dialogIntroPanel.setLineWrap(true); dialogIntroPanel.setWrapStyleWord(true); dialogIntroPanel.setText(m_overwriteDialogIntro); dialogIntroPanel.setEditable(false); dialogIntroPanel.setBackground(m_fileSelector.getBackground()); dialogIntroPanel.setFont(m_font); FileSelectionPanel selectionPanel = new FileSelectionPanel( duplications, m_fileSelector.getCurrentDirectory().getAbsolutePath()); JPanel stacker = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.gridheight = 1; gbc.gridwidth = 1; gbc.weightx = 1f; gbc.weighty = 0f; gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(2, 2, 2, 2); stacker.add(dialogIntroPanel, gbc); gbc.weighty = 1f; gbc.gridy = 1; gbc.insets = new Insets(0, 2, 0, 2); stacker.add(selectionPanel, gbc); m_overwriteDialog = new ModalDialog( m_fileSelector, m_overwriteDialogTitle, m_overwriteDialogOk, m_overwriteDialogCancel, stacker); m_overwriteDialog.setSize(new Dimension(560, 280)); //dialog.setResizable(false); m_overwriteDialog.showDialog(); rtv = m_overwriteDialog.getReturnValue(); } catch (Throwable f) { f.printStackTrace(System.err); } return rtv; } /** * @see java.applet.Applet#start() */ public void start() { if (m_certificateAccepted) { // certificate was accepted, start upload thread m_runner = new Thread(this); m_runner.start(); } else { // certificate was not accepted, show error message displayError(); } } /** * @see java.applet.Applet#stop() */ public void stop() { m_runner = null; } /** * Return all files that are found in the first argument except a matching path suffix is found in the list * of Strings given by the 2nd argument. <p> * * @param fileNames the list of paths to diminish by matching path suffixes of the 2nd argument. * * @param duplications a list of Strings that contains "relative" paths (without absolute location) * * @return all files that are found in the first argument except a matching path suffix is found in the list * of Strings given by the 2nd argument */ private File[] subtractDuplicates(List fileNames, List duplications) { // subtract: String path; Iterator itDuplications = duplications.iterator(); while (itDuplications.hasNext()) { path = (String)itDuplications.next(); fileNames.remove(path); } // no recreate the subtractor list to files: List result = new ArrayList(); File rootPath = m_fileSelector.getCurrentDirectory(); Iterator it = fileNames.iterator(); while (it.hasNext()) { path = (String)it.next(); result.add(new File(rootPath, path)); } return (File[])result.toArray(new File[result.size()]); } /** * @see java.awt.Component#update(java.awt.Graphics) */ public void update(Graphics g) { paint(g); } /** * Uploads the zipfile to the OpenCms.<p> * * @param uploadFile the zipfile to upload */ private void uploadZipFile(File uploadFile) { m_action = m_actionOutputUpload; repaint(); PostMethod post = new PostMethod(m_targetUrl); try { Part[] parts = new Part[5]; parts[0] = new FilePart(uploadFile.getName(), uploadFile); parts[1] = new StringPart("action", "submitform"); parts[2] = new StringPart("unzipfile", "true"); parts[3] = new StringPart("uploadfolder", m_uploadFolder); parts[4] = new StringPart("clientfolder", m_fileSelector.getCurrentDirectory().getAbsolutePath()); HttpMethodParams methodParams = post.getParams(); methodParams.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); MultipartRequestEntity request = new MultipartRequestEntity(parts, methodParams); post.setRequestEntity(request); // add jsessionid query string String sessionId = getParameter("sessionId"); String query = ";" + C_JSESSIONID.toLowerCase() + "=" + sessionId; post.setQueryString(query); post.addRequestHeader(C_JSESSIONID, sessionId); HttpClient client = new HttpClient(); HttpConnectionParams connectionParams = client.getHttpConnectionManager().getParams(); connectionParams.setConnectionTimeout(5000); // add the session cookie client.getState(); client.getHostConfiguration().getHost(); HttpState initialState = new HttpState(); URI uri = new URI(m_targetUrl, false); Cookie sessionCookie = new Cookie(uri.getHost(), C_JSESSIONID, sessionId, "/", null, false); initialState.addCookie(sessionCookie); client.setState(initialState); // no execute the file upload int status = client.executeMethod(post); if (status == HttpStatus.SC_OK) { //return to the specified url and frame target getAppletContext().showDocument(new URL(m_redirectUrl), m_redirectTargetFrame); } else { // create the error text String error = m_errorLine1 + "\n" + post.getStatusLine(); //JOptionPane.showMessageDialog(this, error, "Error!", JOptionPane.ERROR_MESSAGE); getAppletContext().showDocument( new URL(m_errorUrl + "?action=showerror&uploaderror=" + error), "explorer_files"); } } catch (RuntimeException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { post.releaseConnection(); // finally delete the zipFile on the harddisc uploadFile.delete(); } } /** * Writes the bytes of the file to the zip output stream.<p> * * @param file the name of the file to read * * @param out the zip outputstream * * @throws Exception if something goes wrong */ private void writeFileBytes(File file, OutputStream out) throws Exception { byte[] buffer = new byte[2048]; FileInputStream fileStream = null; int charsRead; int size; try { fileStream = new FileInputStream(file); charsRead = 0; size = new Long(file.length()).intValue(); int readCount = 0; while ((charsRead < size) && (readCount != -1)) { readCount = fileStream.read(buffer); charsRead += readCount; out.write(buffer, 0, readCount); } } catch (IOException e) { throw e; } finally { try { if (fileStream != null) { fileStream.close(); } } catch (IOException e) { // ignore } } } }