source: gli/trunk/src/org/greenstone/gatherer/gui/NewCollectionDetailsPrompt.java@ 17612

Last change on this file since 17612 was 17612, checked in by ak19, 15 years ago

Turned class RemoteGreenstoneServer.java from an all-static class into a regular OOP class. It is now also split into three files (the other two being ActionQueue.java and RemoteGreenstoneServerAction.java).

  • Property svn:keywords set to Author Date Id Revision
File size: 15.5 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Project, NZDL, University of Waikato
9 *
10 * Copyright (C) 2003 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.gui;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.File;
32import java.util.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import javax.swing.text.*;
36import org.greenstone.gatherer.Configuration;
37import org.greenstone.gatherer.Dictionary;
38import org.greenstone.gatherer.Gatherer;
39import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
40import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
41import org.greenstone.gatherer.util.StaticStrings;
42import org.greenstone.gatherer.util.Utility;
43
44public class NewCollectionDetailsPrompt
45 extends ModalDialog {
46
47
48
49 static public boolean titleClashes(String title, File current_config_file) {
50 // An empty collection title never clashes with anything. It may look ugly in the final collection but there is nothing wrong with having no title for a particular language.
51 if(title == null || title.length() == 0) {
52 return false;
53 }
54 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
55 String file_name = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
56 File children[] = collect_directory.listFiles();
57 for(int i = 0; children != null && i < children.length; i++) {
58 if(children[i].isDirectory()) {
59 File config_file = new File(children[i], file_name);
60 if(current_config_file == null || !config_file.equals(current_config_file)) {
61 BasicCollectionConfiguration other_collection = new BasicCollectionConfiguration(config_file);
62 if(other_collection.getName().equalsIgnoreCase(title)) {
63 return true;
64 }
65 other_collection = null;
66 }
67 config_file = null;
68 }
69 }
70 return false;
71 }
72
73 private boolean cancelled;
74 private File base_final;
75 private JButton create_button;
76 private JComboBox base_collection;
77 private JDialog self;
78 private JRadioButton personal_collection_button = null;
79 private JTextArea description;
80 private JTextField title;
81 private String description_final;
82 private String title_final="";
83 static private Dimension COMPONENT_SIZE = new Dimension(230, 25);
84 /** The size of this new collection dialog box. */
85 static private Dimension SIZE = new Dimension(600, 280);
86 static private int FILENAME_SIZE = 8;
87
88 /** Constructor.
89 * @see org.greenstone.gatherer.util.Utility
90 */
91 public NewCollectionDetailsPrompt() {
92 super(Gatherer.g_man, true);
93 this.cancelled = true;
94 this.self = this;
95 // Setup
96 setJMenuBar(new SimpleMenuBar("creatingacollection"));
97 setSize(SIZE);
98 setTitle(Dictionary.get("NewCollectionPrompt.Title"));
99
100 // Model building. Build a model of all of the collections in the gsdl collect directory with the appropriate directories.
101 Vector base_collection_model = new Vector();
102 // need to modify this to base a coll on any collection from any site
103 if (Gatherer.GS3 && !Gatherer.isGsdlRemote) {
104 File sites_dir = new File(Gatherer.getSitesDirectoryPath());
105 File [] sites = sites_dir.listFiles();
106 for (int i=0; i<sites.length; i++) {
107 File collect_directory = new File(sites_dir + File.separator + sites[i].getName() + File.separator + "collect");
108 if (collect_directory.exists()) {
109 addCollectionsToModel(base_collection_model, collect_directory, sites[i].getName());
110 }
111 }
112 } else {
113 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
114 addCollectionsToModel(base_collection_model, collect_directory, null);
115 }
116
117 // Sort the result.
118 Collections.sort(base_collection_model);
119 base_collection_model.add(0, new Item(null, Dictionary.get("NewCollectionPrompt.NewCollection")));
120
121 // Creation
122 JPanel content_pane = (JPanel) getContentPane();
123 content_pane.setOpaque(true);
124 JPanel upper_pane = new JPanel();
125 JLabel instructions_label = new JLabel(Dictionary.get("NewCollectionPrompt.Instructions"));
126
127 JPanel title_pane = new JPanel();
128 JLabel title_label = new JLabel(Dictionary.get("CDM.General.Collection_Name"));
129 title = new JTextField();
130 title.setPreferredSize(COMPONENT_SIZE);
131 title.setToolTipText(Dictionary.get("CDM.General.Collection_Name_Tooltip"));
132 JLabel name_label = new JLabel(Dictionary.get("NewCollectionPrompt.Collection_Name"));
133
134 JPanel center_pane = new JPanel();
135 JPanel description_pane = new JPanel();
136 JLabel description_label = new JLabel(Dictionary.get("NewCollectionPrompt.Collection_Description"));
137 description = new JTextArea();
138 description.setBackground(Configuration.getColor("coloring.editable_background", false));
139 description.setForeground(Configuration.getColor("coloring.editable_foreground", false));
140 description.setRows(5);
141 description.setToolTipText(Dictionary.get("CDM.General.Collection_Extra_Tooltip"));
142
143 JPanel bottom_pane = new JPanel();
144 // Base Collection
145 JPanel base_collection_pane = new JPanel();
146 JLabel base_collection_label = new JLabel(Dictionary.get("NewCollectionPrompt.Base_Collection"));
147 base_collection = new JComboBox(base_collection_model);
148 base_collection.setOpaque(false);
149 base_collection.setToolTipText(Dictionary.get("NewCollectionPrompt.Base_Collection_Tooltip"));
150
151 JPanel collection_scope_pane = new JPanel();
152 personal_collection_button = new JRadioButton(Dictionary.get("NewCollectionPrompt.Collection_Scope_Personal"));
153 personal_collection_button.setToolTipText(Dictionary.get("NewCollectionPrompt.Collection_Scope_Personal_Tooltip"));
154 personal_collection_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
155 personal_collection_button.setOpaque(false);
156 JRadioButton shared_collection_button = new JRadioButton(Dictionary.get("NewCollectionPrompt.Collection_Scope_Shared"));
157 shared_collection_button.setToolTipText(Dictionary.get("NewCollectionPrompt.Collection_Scope_Shared_Tooltip"));
158 shared_collection_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
159 shared_collection_button.setOpaque(false);
160 ButtonGroup collection_scope_group = new ButtonGroup();
161 collection_scope_group.add(personal_collection_button);
162 collection_scope_group.add(shared_collection_button);
163 personal_collection_button.setSelected(true);
164
165 JPanel button_pane = new JPanel();
166 create_button = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));
167 JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
168
169 // Connection
170 cancel_button.addActionListener(new CancelListener());
171 create_button.addActionListener(new CreateListener());
172 description.addKeyListener(new DescriptionListener());
173
174 // Layout
175 title_pane.setLayout(new BorderLayout(5,0));
176 title_pane.add(title_label, BorderLayout.WEST);
177 title_pane.add(title, BorderLayout.CENTER);
178
179 upper_pane.setLayout(new GridLayout(2,1));
180 upper_pane.add(instructions_label);
181 upper_pane.add(title_pane);
182
183 description_pane.setLayout(new BorderLayout());
184 description_pane.add(description_label, BorderLayout.NORTH);
185 description_pane.add(new JScrollPane(description), BorderLayout.CENTER);
186
187 base_collection_pane.setLayout(new BorderLayout(5,0));
188 base_collection_pane.add(base_collection_label, BorderLayout.WEST);
189 base_collection_pane.add(base_collection, BorderLayout.CENTER);
190
191 collection_scope_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
192 collection_scope_pane.setLayout(new GridLayout(1,2));
193 collection_scope_pane.add(personal_collection_button);
194 collection_scope_pane.add(shared_collection_button);
195
196 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
197 center_pane.setLayout(new BorderLayout());
198 center_pane.add(description_pane, BorderLayout.CENTER);
199
200 bottom_pane.setLayout(new BorderLayout());
201 bottom_pane.add(base_collection_pane, BorderLayout.NORTH);
202 if (Gatherer.isGsdlRemote) {
203 bottom_pane.add(collection_scope_pane, BorderLayout.CENTER);
204 bottom_pane.add(button_pane, BorderLayout.SOUTH);
205 }
206 else {
207 bottom_pane.add(button_pane, BorderLayout.CENTER);
208 }
209
210 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
211 button_pane.setLayout(new GridLayout(1,2));
212 button_pane.add(create_button);
213 button_pane.add(cancel_button);
214
215 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
216 content_pane.setLayout(new BorderLayout());
217 content_pane.add(upper_pane, BorderLayout.NORTH);
218 content_pane.add(center_pane, BorderLayout.CENTER);
219 content_pane.add(bottom_pane, BorderLayout.SOUTH);
220 // Final dialog setup & positioning.
221 Dimension screen_size = Configuration.screen_size;
222 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
223 setVisible(true);
224 }
225
226 public boolean isCancelled() {
227 return cancelled;
228 }
229
230 public File getBase() {
231 return base_final;
232 }
233
234 public String getDescription() {
235 return description_final;
236 }
237
238 /** Generates the collection short filename by taking the first eight characters of the title (spaces removed) and then adjusting by further truncating and then adding an unique suffix as necessary.
239 * @return the filename as a String
240 */
241 public String getName()
242 {
243 // Retrieve the first 8 non-whitespace ASCII characters of title_final.
244 StringBuffer name_buffer = new StringBuffer("");
245 for (int i = 0, u = 0; (i < title_final.length() && u < 8); i++) {
246 // To be safe we make sure the internal collection name (folder name) contains only ASCII characters
247 char c = title_final.charAt(i);
248 if ((int) c < 128 && Character.isLetterOrDigit(c)) {
249 name_buffer.append(Character.toLowerCase(c));
250 u++;
251 }
252 }
253
254 // Use "col" as the base collection name if we have nothing left
255 if (name_buffer.length() == 0) {
256 name_buffer = new StringBuffer("col");
257 }
258
259 // Remote collections that aren't shared have the user's username prefixed to the collection name
260 if (Gatherer.isGsdlRemote && personal_collection_button.isSelected()) {
261 name_buffer = new StringBuffer(Gatherer.remoteGreenstoneServer.getUsername() + "-" + name_buffer.toString());
262 }
263
264 // We need to ensure the filename is unique
265 int counter = 0;
266 StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
267 while(filenameClashes(new_name_buffer.toString())) {
268 new_name_buffer = new StringBuffer(name_buffer.toString());
269 counter++;
270 String suffix = String.valueOf(counter);
271 // If we have to truncate the namestring so as to fit the suffix
272 if(suffix.length() + new_name_buffer.length() > 8) {
273 new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
274 }
275 // Or just append it if that isn't necessary
276 else {
277 new_name_buffer.append(suffix);
278 }
279 }
280
281 // All done
282 return new_name_buffer.toString();
283 }
284
285 private boolean filenameClashes(String filename)
286 {
287 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
288 File children[] = collect_directory.listFiles();
289 for(int i = 0; children != null && i < children.length; i++) {
290 if(children[i].getName().equals(filename)) {
291 return true;
292 }
293 }
294 return false;
295 }
296
297 public String getTitle() {
298 return title_final;
299 }
300
301 private void addCollectionsToModel(Vector base_collection_model, File collect_directory, String site) {
302 File[] possible_collections = collect_directory.listFiles();
303 String file_name = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
304 for (int i = 0; possible_collections != null && i < possible_collections.length; i++) {
305 // If the directory has a etc/collect.cfg file then it looks like a collection
306 File collect_cfg_file = new File(possible_collections[i], file_name);
307 if (collect_cfg_file.exists()) {
308 // If the directory has a metadata/ then the collection can be used as a base
309 File metadata_directory = new File(possible_collections[i], "metadata");
310 if (metadata_directory.exists()) {
311 // Add to model
312 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
313 if (Gatherer.GS3 && site != null) {
314 collect_cfg.setSite(site);
315 }
316 Item item = new Item(possible_collections[i], collect_cfg);
317 if (!base_collection_model.contains(item)) {
318 base_collection_model.add(item);
319 }
320 }
321 }
322 }
323
324 }
325
326 private class CancelListener
327 implements ActionListener {
328 public void actionPerformed(ActionEvent event) {
329 cancelled = true;
330 self.dispose();
331 }
332 }
333
334
335 private class CreateListener
336 implements ActionListener {
337
338 public void actionPerformed(ActionEvent event) {
339 // Validate.
340 title_final = title.getText();
341 if(title_final.length() == 0) {
342 JOptionPane jOptionPane=new JOptionPane();
343 jOptionPane.setOpaque(!Utility.isMac());
344 jOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
345 return;
346 }
347 // We must ensure that the collection title is unique. This is a pain in the nether regions as we are forced to load the collect.cfg of each other collection in turn looking for a conflicting title
348 else {
349 if(titleClashes(title_final, null)) {
350 JOptionPane jOptionPane=new JOptionPane();
351 jOptionPane.setOpaque(!Utility.isMac());
352 if (jOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
353 return;
354 }
355 }
356 }
357
358 description_final = description.getText();
359
360 // If we got this far there are no errors.
361 Item item_final = (Item) base_collection.getSelectedItem();
362 base_final = item_final.getFile();
363
364 cancelled = false;
365
366 self.dispose();
367 }
368 }
369
370 private class DescriptionListener
371 extends KeyAdapter {
372 public void keyPressed(KeyEvent event) {
373 if(event.getKeyCode() == KeyEvent.VK_TAB) {
374 event.consume();
375 base_collection.grabFocus();
376 }
377 }
378 }
379
380 private class Item
381 implements Comparable {
382 private BasicCollectionConfiguration config;
383 private File file;
384 private String name;
385 public Item(File file, BasicCollectionConfiguration config) {
386 this.config = config;
387 this.file = file;
388 this.name = null;
389 }
390 public Item(File file, String name) {
391 this.config = null;
392 this.file = file;
393 this.name = name;
394 }
395 public int compareTo(Object other) {
396 return toString().toLowerCase().compareTo(other.toString().toLowerCase());
397 }
398 public boolean equals(Object other) {
399 return compareTo(other) == 0;
400 }
401 public File getFile() {
402 return file;
403 }
404 public String toString() {
405 if(name == null && config != null) {
406 name = config.toString();
407 }
408 return name;
409 }
410 }
411}
412
413
414
Note: See TracBrowser for help on using the repository browser.