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

Last change on this file since 20957 was 18947, checked in by kjdon, 15 years ago

don't use existence of metadata directory as not collect group, as there may be one there. Look at the collect.cfg first, then test metadata dir

  • Property svn:keywords set to Author Date Id Revision
File size: 17.8 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.setComponentOrientation(Dictionary.getOrientation());
95 this.self = this;
96 // Setup
97 setJMenuBar(new SimpleMenuBar("creatingacollection"));
98 setSize(SIZE);
99 setTitle(Dictionary.get("NewCollectionPrompt.Title"));
100
101 // Model building. Build a model of all of the collections in the gsdl collect directory with the appropriate directories.
102 Vector base_collection_model = new Vector();
103 // need to modify this to base a coll on any collection from any site
104 if (Gatherer.GS3 && !Gatherer.isGsdlRemote) {
105 File sites_dir = new File(Gatherer.getSitesDirectoryPath());
106 File [] sites = sites_dir.listFiles();
107 for (int i=0; i<sites.length; i++) {
108 File collect_directory = new File(sites_dir + File.separator + sites[i].getName() + File.separator + "collect");
109 if (collect_directory.exists()) {
110 addCollectionsToModel(base_collection_model, collect_directory, sites[i].getName());
111 }
112 }
113 } else {
114 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
115 addCollectionsToModel(base_collection_model, collect_directory, null);
116 }
117
118 // Sort the result.
119 Collections.sort(base_collection_model);
120 base_collection_model.add(0, new Item(null, Dictionary.get("NewCollectionPrompt.NewCollection")));
121
122 // Creation
123 JPanel content_pane = (JPanel) getContentPane();
124 content_pane.setComponentOrientation(Dictionary.getOrientation());
125 content_pane.setOpaque(true);
126 JPanel upper_pane = new JPanel();
127 upper_pane.setComponentOrientation(Dictionary.getOrientation());
128 JLabel instructions_label = new JLabel(Dictionary.get("NewCollectionPrompt.Instructions"));
129 instructions_label.setComponentOrientation(Dictionary.getOrientation());
130
131 JPanel title_pane = new JPanel();
132 title_pane.setComponentOrientation(Dictionary.getOrientation());
133 JLabel title_label = new JLabel(Dictionary.get("CDM.General.Collection_Name"));
134 title_label.setComponentOrientation(Dictionary.getOrientation());
135 title = new JTextField();
136 title.setComponentOrientation(Dictionary.getOrientation());
137 title.setPreferredSize(COMPONENT_SIZE);
138 title.setToolTipText(Dictionary.get("CDM.General.Collection_Name_Tooltip"));
139 JLabel name_label = new JLabel(Dictionary.get("NewCollectionPrompt.Collection_Name"));
140 name_label.setComponentOrientation(Dictionary.getOrientation());
141
142 JPanel center_pane = new JPanel();
143 center_pane.setComponentOrientation(Dictionary.getOrientation());
144 JPanel description_pane = new JPanel();
145 description_pane.setComponentOrientation(Dictionary.getOrientation());
146 JLabel description_label = new JLabel(Dictionary.get("NewCollectionPrompt.Collection_Description"));
147 description_label.setComponentOrientation(Dictionary.getOrientation());
148 description = new JTextArea();
149 description.setComponentOrientation(Dictionary.getOrientation());
150 description.setBackground(Configuration.getColor("coloring.editable_background", false));
151 description.setForeground(Configuration.getColor("coloring.editable_foreground", false));
152 description.setRows(5);
153 description.setToolTipText(Dictionary.get("CDM.General.Collection_Extra_Tooltip"));
154
155 JPanel bottom_pane = new JPanel();
156 bottom_pane.setComponentOrientation(Dictionary.getOrientation());
157 // Base Collection
158 JPanel base_collection_pane = new JPanel();
159 base_collection_pane.setComponentOrientation(Dictionary.getOrientation());
160
161 JLabel base_collection_label = new JLabel(Dictionary.get("NewCollectionPrompt.Base_Collection"));
162 base_collection_label.setComponentOrientation(Dictionary.getOrientation());
163
164 base_collection = new JComboBox(base_collection_model);
165 base_collection.setComponentOrientation(Dictionary.getOrientation());
166 base_collection.setOpaque(false);
167 base_collection.setToolTipText(Dictionary.get("NewCollectionPrompt.Base_Collection_Tooltip"));
168
169 JPanel collection_scope_pane = new JPanel();
170 collection_scope_pane.setComponentOrientation(Dictionary.getOrientation());
171
172 personal_collection_button = new JRadioButton(Dictionary.get("NewCollectionPrompt.Collection_Scope_Personal"));
173 personal_collection_button.setToolTipText(Dictionary.get("NewCollectionPrompt.Collection_Scope_Personal_Tooltip"));
174 personal_collection_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
175 personal_collection_button.setOpaque(false);
176 personal_collection_button.setComponentOrientation(Dictionary.getOrientation());
177
178 JRadioButton shared_collection_button = new JRadioButton(Dictionary.get("NewCollectionPrompt.Collection_Scope_Shared"));
179 shared_collection_button.setToolTipText(Dictionary.get("NewCollectionPrompt.Collection_Scope_Shared_Tooltip"));
180 shared_collection_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
181 shared_collection_button.setOpaque(false);
182 shared_collection_button.setComponentOrientation(Dictionary.getOrientation());
183
184 ButtonGroup collection_scope_group = new ButtonGroup();
185 collection_scope_group.add(personal_collection_button);
186 collection_scope_group.add(shared_collection_button);
187 personal_collection_button.setSelected(true);
188
189 JPanel button_pane = new JPanel();
190 button_pane.setComponentOrientation(Dictionary.getOrientation());
191 create_button = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));
192 JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
193
194 // Connection
195 cancel_button.addActionListener(new CancelListener());
196 create_button.addActionListener(new CreateListener());
197 description.addKeyListener(new DescriptionListener());
198
199 // Layout
200 title_pane.setLayout(new BorderLayout(5,0));
201 title_pane.add(title_label, BorderLayout.LINE_START);
202 title_pane.add(title, BorderLayout.CENTER);
203
204 upper_pane.setLayout(new GridLayout(2,1));
205 upper_pane.add(instructions_label);
206 upper_pane.add(title_pane);
207
208 JScrollPane scrol_tmp;
209
210 description_pane.setLayout(new BorderLayout());
211 description_pane.add(description_label, BorderLayout.NORTH);
212 scrol_tmp=new JScrollPane(description);
213 scrol_tmp.setComponentOrientation(Dictionary.getOrientation());
214 description_pane.add(scrol_tmp, BorderLayout.CENTER);
215
216 base_collection_pane.setLayout(new BorderLayout(5,0));
217 base_collection_pane.add(base_collection_label, BorderLayout.LINE_START);
218 base_collection_pane.add(base_collection, BorderLayout.CENTER);
219
220 collection_scope_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
221 collection_scope_pane.setLayout(new GridLayout(1,2));
222 collection_scope_pane.add(personal_collection_button);
223 collection_scope_pane.add(shared_collection_button);
224
225 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
226 center_pane.setLayout(new BorderLayout());
227 center_pane.add(description_pane, BorderLayout.CENTER);
228
229 bottom_pane.setLayout(new BorderLayout());
230 bottom_pane.add(base_collection_pane, BorderLayout.NORTH);
231 if (Gatherer.isGsdlRemote) {
232 bottom_pane.add(collection_scope_pane, BorderLayout.CENTER);
233 bottom_pane.add(button_pane, BorderLayout.SOUTH);
234 }
235 else {
236 bottom_pane.add(button_pane, BorderLayout.CENTER);
237 }
238
239 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
240 button_pane.setLayout(new GridLayout(1,2));
241 button_pane.add(create_button);
242 button_pane.add(cancel_button);
243
244 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
245 content_pane.setLayout(new BorderLayout());
246 content_pane.add(upper_pane, BorderLayout.NORTH);
247 content_pane.add(center_pane, BorderLayout.CENTER);
248 content_pane.add(bottom_pane, BorderLayout.SOUTH);
249 // Final dialog setup & positioning.
250 getRootPane().setDefaultButton(create_button);
251 Dimension screen_size = Configuration.screen_size;
252 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
253 setVisible(true);
254 }
255
256 public boolean isCancelled() {
257 return cancelled;
258 }
259
260 public File getBase() {
261 return base_final;
262 }
263
264 public String getDescription() {
265 return description_final;
266 }
267
268 /** 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.
269 * @return the filename as a String
270 */
271 public String getName()
272 {
273 // Retrieve the first 8 non-whitespace ASCII characters of title_final.
274 StringBuffer name_buffer = new StringBuffer("");
275 for (int i = 0, u = 0; (i < title_final.length() && u < 8); i++) {
276 // To be safe we make sure the internal collection name (folder name) contains only ASCII characters
277 char c = title_final.charAt(i);
278 if ((int) c < 128 && Character.isLetterOrDigit(c)) {
279 name_buffer.append(Character.toLowerCase(c));
280 u++;
281 }
282 }
283
284 // Use "col" as the base collection name if we have nothing left
285 if (name_buffer.length() == 0) {
286 name_buffer = new StringBuffer("col");
287 }
288
289 // Remote collections that aren't shared have the user's username prefixed to the collection name
290 if (Gatherer.isGsdlRemote && personal_collection_button.isSelected()) {
291 name_buffer = new StringBuffer(Gatherer.remoteGreenstoneServer.getUsername() + "-" + name_buffer.toString());
292 }
293
294 // We need to ensure the filename is unique
295 int counter = 0;
296 StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
297 while(filenameClashes(new_name_buffer.toString())) {
298 new_name_buffer = new StringBuffer(name_buffer.toString());
299 counter++;
300 String suffix = String.valueOf(counter);
301 // If we have to truncate the namestring so as to fit the suffix
302 if(suffix.length() + new_name_buffer.length() > 8) {
303 new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
304 }
305 // Or just append it if that isn't necessary
306 else {
307 new_name_buffer.append(suffix);
308 }
309 }
310
311 // All done
312 return new_name_buffer.toString();
313 }
314
315 private boolean filenameClashes(String filename)
316 {
317 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
318 File children[] = collect_directory.listFiles();
319 for(int i = 0; children != null && i < children.length; i++) {
320 if(children[i].getName().equals(filename)) {
321 return true;
322 }
323 }
324 return false;
325 }
326
327 public String getTitle() {
328 return title_final;
329 }
330
331 private void addCollectionsToModel(Vector base_collection_model, File collect_directory, String site) {
332 File[] possible_collections = collect_directory.listFiles();
333 String file_name = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
334 for (int i = 0; possible_collections != null && i < possible_collections.length; i++) {
335 // If the directory has a etc/collect.cfg file then it looks like a collection
336 File collect_cfg_file = new File(possible_collections[i], file_name);
337 if (collect_cfg_file.exists()) {
338 // Check for group coll: Check the collect.cfg for collectgroup=true
339 BasicCollectionConfiguration config = new BasicCollectionConfiguration(collect_cfg_file);
340 if (config.getCollectGroup().equals("true")) {
341 // try subdirs in here
342 addCollectionsToModel(base_collection_model, possible_collections[i], site);
343 }
344 else {
345
346 // If the directory has a metadata/ then the collection can be used as a base
347 File metadata_directory = new File(possible_collections[i], "metadata");
348 if (metadata_directory.exists()) {
349 // Add to model
350 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
351 if (Gatherer.GS3 && site != null) {
352 collect_cfg.setSite(site);
353 }
354 Item item = new Item(possible_collections[i], collect_cfg);
355 if (!base_collection_model.contains(item)) {
356 base_collection_model.add(item);
357 }
358 }
359 }
360 }
361 }
362
363 }
364
365 private class CancelListener
366 implements ActionListener {
367 public void actionPerformed(ActionEvent event) {
368 cancelled = true;
369 self.dispose();
370 }
371 }
372
373
374 private class CreateListener
375 implements ActionListener {
376
377 public void actionPerformed(ActionEvent event) {
378 // Validate.
379 title_final = title.getText();
380 if(title_final.length() == 0) {
381 JOptionPane jOptionPane=new JOptionPane();
382 jOptionPane.setComponentOrientation(Dictionary.getOrientation());
383 jOptionPane.setOpaque(!Utility.isMac());
384 jOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
385 return;
386 }
387 // 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
388 else {
389 if(titleClashes(title_final, null)) {
390 JOptionPane jOptionPane=new JOptionPane();
391 jOptionPane.setComponentOrientation(Dictionary.getOrientation());
392 jOptionPane.setOpaque(!Utility.isMac());
393 if (jOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
394 return;
395 }
396 }
397 }
398
399 description_final = description.getText();
400
401 // If we got this far there are no errors.
402 Item item_final = (Item) base_collection.getSelectedItem();
403 base_final = item_final.getFile();
404
405 cancelled = false;
406
407 self.dispose();
408 }
409 }
410
411 private class DescriptionListener
412 extends KeyAdapter {
413 public void keyPressed(KeyEvent event) {
414 if(event.getKeyCode() == KeyEvent.VK_TAB) {
415 event.consume();
416 base_collection.grabFocus();
417 }
418 }
419 }
420
421 private class Item
422 implements Comparable {
423 private BasicCollectionConfiguration config;
424 private File file;
425 private String name;
426 public Item(File file, BasicCollectionConfiguration config) {
427 this.config = config;
428 this.file = file;
429 this.name = null;
430 }
431 public Item(File file, String name) {
432 this.config = null;
433 this.file = file;
434 this.name = name;
435 }
436 public int compareTo(Object other) {
437 return toString().toLowerCase().compareTo(other.toString().toLowerCase());
438 }
439 public boolean equals(Object other) {
440 return compareTo(other) == 0;
441 }
442 public File getFile() {
443 return file;
444 }
445 public String toString() {
446 if(name == null && config != null) {
447 name = config.toString();
448 }
449 return name;
450 }
451 }
452}
453
454
455
Note: See TracBrowser for help on using the repository browser.