001    /*
002     * 
003     * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.frontend.fileupload;
025    
026    import java.applet.AppletContext;
027    import java.awt.Color;
028    import java.awt.GridBagConstraints;
029    import java.awt.GridBagLayout;
030    import java.awt.Insets;
031    import java.awt.event.ActionEvent;
032    import java.awt.event.ActionListener;
033    import java.awt.event.KeyAdapter;
034    import java.awt.event.KeyEvent;
035    import java.io.File;
036    import java.net.URL;
037    import java.util.HashSet;
038    import java.util.Locale;
039    import java.util.ResourceBundle;
040    import java.util.Set;
041    import java.util.StringTokenizer;
042    
043    import javax.swing.BorderFactory;
044    import javax.swing.JApplet;
045    import javax.swing.JButton;
046    import javax.swing.JFileChooser;
047    import javax.swing.JLabel;
048    import javax.swing.JPanel;
049    import javax.swing.JTextField;
050    import javax.swing.filechooser.FileFilter;
051    
052    /**
053     * This applet displays a GUI to upload files and directories to the server.
054     * 
055     * @author Harald Richter
056     * @author Frank Lützenkirchen
057     * @author Jens Kupferschmidt
058     * @author Thomas Scheffler (yagee)
059     * 
060     * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
061     */
062    public class MCRUploadApplet extends JApplet {
063        private static final long serialVersionUID = -118475099247635561L;
064    
065        protected String uploadId;
066    
067        protected String peerURL;
068    
069        protected String targetURL;
070    
071        protected JButton chooserButton;
072    
073        protected JTextField locationField;
074    
075        protected JButton locationButton;
076    
077        protected JFileChooser locationChooser;
078    
079        protected static File lastDirectory;
080    
081        private static final File DRIVE_C = new File("C:\\");
082    
083        public void init() {
084            uploadId = getParameter("uploadId");
085            targetURL = getParameter("url");
086            String httpSession = getParameter("httpSession");
087            peerURL = addSessionInfo(getParameter("ServletsBase") + "MCRUploadServlet", httpSession);
088    
089            // If true, applet allows to select multiple files and directories.
090            // If false, only a single file can be selected. Default is true.
091            boolean selectMultiple = !"false".equals(getParameter("selectMultiple"));
092    
093            // List of file extensions to accept separated by comma or spaces,
094            // default is to accept all files
095            final String acceptFileTypes = getParameter("acceptFileTypes");
096    
097            System.out.println("Will connect with: " + peerURL);
098            Color bg = getColorParameter("background-color");
099            System.out.println("Background color: " + bg.toString());
100            setBackground(bg);
101            setLocale();
102            System.out.println("Last working directory: " + ((lastDirectory == null) ? null : lastDirectory.getAbsolutePath()));
103    
104            chooserButton = new JButton(translateI18N("MCRUploadApplet.select"));
105            chooserButton.addActionListener(new ActionListener() {
106                public void actionPerformed(ActionEvent e) {
107                    handleChooserButton();
108                }
109            });
110    
111            locationField = new JTextField(30);
112            locationField.addKeyListener(new KeyAdapter() {
113                public void keyTyped(KeyEvent e) {
114                    locationButton.setEnabled(locationField.getText().length() > 0);
115                }
116            });
117    
118            locationButton = new JButton(translateI18N("MCRUploadApplet.submit"));
119            locationButton.setEnabled(false);
120            locationButton.addActionListener(new ActionListener() {
121                public void actionPerformed(ActionEvent e) {
122                    handleLocationButton();
123                }
124            });
125    
126            locationChooser = new JFileChooser();
127            locationChooser.setFileSelectionMode(selectMultiple ? JFileChooser.FILES_AND_DIRECTORIES : JFileChooser.FILES_ONLY);
128            locationChooser.setMultiSelectionEnabled(selectMultiple);
129    
130            // Add a file filter to accept only files with certain extensions
131            if ((acceptFileTypes != null) && (acceptFileTypes.trim().length() > 0) && (!"*".equals(acceptFileTypes.trim()))) {
132                locationChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
133                locationChooser.setFileFilter(new FileFilter() {
134                    Set accepted = new HashSet();
135    
136                    public boolean accept(File f) {
137                        if (accepted.isEmpty()) {
138                            StringTokenizer st = new StringTokenizer(acceptFileTypes, " ,;");
139                            while (st.hasMoreTokens())
140                                accepted.add(st.nextToken());
141                        }
142                        String[] ext = f.getName().split("\\.");
143                        return accepted.contains(ext[ext.length - 1]);
144                    }
145    
146                    public String getDescription() {
147                        return acceptFileTypes;
148                    }
149                });
150            }
151    
152            if (lastDirectory != null) {
153                locationChooser.setCurrentDirectory(lastDirectory);
154            } else if (DRIVE_C.exists()) {
155                locationChooser.setCurrentDirectory(DRIVE_C);
156            }
157    
158            JPanel content = new JPanel();
159            setContentPane(content);
160    
161            GridBagLayout gbl = new GridBagLayout();
162            GridBagConstraints gbc = new GridBagConstraints();
163            content.setLayout(gbl);
164            content.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
165            content.setBackground(bg);
166    
167            JLabel jlChoose = new JLabel(translateI18N("MCRUploadApplet.dirsel"));
168            gbc.insets = new Insets(2, 2, 2, 2);
169            gbc.gridx = 1;
170            gbc.gridy = 1;
171            gbc.anchor = GridBagConstraints.WEST;
172            gbc.fill = GridBagConstraints.NONE;
173            gbl.setConstraints(jlChoose, gbc);
174            content.add(jlChoose);
175    
176            gbc.gridx = 2;
177            gbc.gridy = 1;
178            gbl.setConstraints(chooserButton, gbc);
179            content.add(chooserButton);
180    
181            JLabel jlInput = new JLabel(translateI18N("MCRUploadApplet.altsel"));
182            gbc.gridx = 1;
183            gbc.gridy = 2;
184            gbl.setConstraints(jlInput, gbc);
185            content.add(jlInput);
186    
187            gbc.gridx = 1;
188            gbc.gridy = 3;
189            gbc.fill = GridBagConstraints.HORIZONTAL;
190            gbl.setConstraints(locationField, gbc);
191            content.add(locationField);
192    
193            gbc.gridx = 2;
194            gbc.gridy = 3;
195            gbc.fill = GridBagConstraints.NONE;
196            gbl.setConstraints(locationButton, gbc);
197            content.add(locationButton);
198        }
199    
200        protected void handleLocationButton() {
201            File[] selectedFiles = new File[1];
202            selectedFiles[0] = new File(locationField.getText());
203            doUpload(selectedFiles);
204        }
205    
206        protected void handleChooserButton() {
207            int result = locationChooser.showDialog(this, translateI18N("MCRUploadApplet.choose"));
208    
209            if (result == JFileChooser.APPROVE_OPTION) {
210                System.out.println("Saving current working directory: " + locationChooser.getCurrentDirectory().getAbsolutePath());
211                lastDirectory = locationChooser.getCurrentDirectory();
212                doUpload(locationChooser.getSelectedFiles());
213            }
214        }
215    
216        protected void doUpload(final File[] selectedFiles) {
217            chooserButton.setEnabled(false);
218            locationButton.setEnabled(false);
219            locationField.setEnabled(false);
220    
221            Thread th = new Thread() {
222                public void run() {
223                    MCRUploadCommunicator comm = new MCRUploadCommunicator(peerURL, uploadId, MCRUploadApplet.this);
224                    comm.uploadFiles(selectedFiles);
225                }
226            };
227            th.start();
228        }
229    
230        void returnToURL() {
231            try {
232                URL url = new URL(targetURL);
233                AppletContext context = this.getAppletContext();
234                context.showDocument(url);
235            } catch (Exception exc) {
236                System.out.println("Unable to return to URL " + targetURL);
237                System.out.println(exc.getMessage());
238                exc.printStackTrace();
239            }
240        }
241    
242        /**
243         * provides translation for the given label (property key).
244         * 
245         * Use the current locale that is needed for translation.
246         * 
247         * @param label
248         * @return translated String
249         */
250        private final String translateI18N(String label) {
251            String result;
252            Locale currentLocale = getLocale();
253            try {
254                ResourceBundle message = ResourceBundle.getBundle("messages", currentLocale);
255                result = message.getString(label);
256            } catch (java.util.MissingResourceException mre) {
257                result = "???" + label + "???";
258                System.err.println(mre.getMessage());
259            }
260    
261            return result;
262        }
263    
264        private final Color getColorParameter(String name) {
265            String value = getParameter(name);
266            if (value == null) {
267                System.err.println("Did not find color parameter: " + name);
268                return Color.WHITE; // as a default if parameter is missing
269            }
270            int rgbValue;
271            try {
272                rgbValue = Integer.parseInt(value.substring(1), 16);
273            } catch (NumberFormatException e) {
274                System.err.println("Color parameter " + name + " has no valid value: " + value);
275                // in this case return red
276                return new Color((float) 1.0, (float) 0.0, (float) 0.0);
277            }
278            return new Color(rgbValue);
279        }
280    
281        private String addSessionInfo(String url, String sessionId) {
282    
283            if ((url == null) || (sessionId == null)) {
284                return url;
285            }
286            String path = url;
287            String query = "";
288            int queryPos = url.indexOf('?');
289            if (queryPos >= 0) {
290                path = url.substring(0, queryPos);
291                query = url.substring(queryPos);
292            }
293            StringBuffer sb = new StringBuffer(path);
294            sb.append(";jsessionid=");
295            sb.append(sessionId);
296            sb.append(query);
297            return sb.toString();
298        }
299    
300        private void setLocale() {
301            String value = getParameter("locale");
302            if (value != null) {
303                setLocale(new Locale(value));
304            }
305        }
306    
307    }