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

Last change on this file since 14361 was 14361, checked in by qq6, 17 years ago

fixed a bug of finding collections under the site

  • Property svn:keywords set to Author Date Id Revision
File size: 15.3 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.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
154 personal_collection_button.setOpaque(false);
155 JRadioButton shared_collection_button = new JRadioButton(Dictionary.get("NewCollectionPrompt.Collection_Scope_Shared"));
156 shared_collection_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
157 shared_collection_button.setOpaque(false);
158 ButtonGroup collection_scope_group = new ButtonGroup();
159 collection_scope_group.add(personal_collection_button);
160 collection_scope_group.add(shared_collection_button);
161 personal_collection_button.setSelected(true);
162
163 JPanel button_pane = new JPanel();
164 create_button = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));
165 JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
166
167 // Connection
168 cancel_button.addActionListener(new CancelListener());
169 create_button.addActionListener(new CreateListener());
170 description.addKeyListener(new DescriptionListener());
171
172 // Layout
173 title_pane.setLayout(new BorderLayout(5,0));
174 title_pane.add(title_label, BorderLayout.WEST);
175 title_pane.add(title, BorderLayout.CENTER);
176
177 upper_pane.setLayout(new GridLayout(2,1));
178 upper_pane.add(instructions_label);
179 upper_pane.add(title_pane);
180
181 description_pane.setLayout(new BorderLayout());
182 description_pane.add(description_label, BorderLayout.NORTH);
183 description_pane.add(new JScrollPane(description), BorderLayout.CENTER);
184
185 base_collection_pane.setLayout(new BorderLayout(5,0));
186 base_collection_pane.add(base_collection_label, BorderLayout.WEST);
187 base_collection_pane.add(base_collection, BorderLayout.CENTER);
188
189 collection_scope_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
190 collection_scope_pane.setLayout(new GridLayout(1,2));
191 collection_scope_pane.add(personal_collection_button);
192 collection_scope_pane.add(shared_collection_button);
193
194 center_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
195 center_pane.setLayout(new BorderLayout());
196 center_pane.add(description_pane, BorderLayout.CENTER);
197
198 bottom_pane.setLayout(new BorderLayout());
199 bottom_pane.add(base_collection_pane, BorderLayout.NORTH);
200 if (Gatherer.isGsdlRemote) {
201 bottom_pane.add(collection_scope_pane, BorderLayout.CENTER);
202 bottom_pane.add(button_pane, BorderLayout.SOUTH);
203 }
204 else {
205 bottom_pane.add(button_pane, BorderLayout.CENTER);
206 }
207
208 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
209 button_pane.setLayout(new GridLayout(1,2));
210 button_pane.add(create_button);
211 button_pane.add(cancel_button);
212
213 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
214 content_pane.setLayout(new BorderLayout());
215 content_pane.add(upper_pane, BorderLayout.NORTH);
216 content_pane.add(center_pane, BorderLayout.CENTER);
217 content_pane.add(bottom_pane, BorderLayout.SOUTH);
218 // Final dialog setup & positioning.
219 Dimension screen_size = Configuration.screen_size;
220 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
221 setVisible(true);
222 }
223
224 public boolean isCancelled() {
225 return cancelled;
226 }
227
228 public File getBase() {
229 return base_final;
230 }
231
232 public String getDescription() {
233 return description_final;
234 }
235
236 /** 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.
237 * @return the filename as a String
238 */
239 public String getName()
240 {
241 // Retrieve the first 8 non-whitespace ASCII characters of title_final.
242 StringBuffer name_buffer = new StringBuffer("");
243 for (int i = 0, u = 0; (i < title_final.length() && u < 8); i++) {
244 // To be safe we make sure the internal collection name (folder name) contains only ASCII characters
245 char c = title_final.charAt(i);
246 if ((int) c < 128 && Character.isLetterOrDigit(c)) {
247 name_buffer.append(Character.toLowerCase(c));
248 u++;
249 }
250 }
251
252 // Use "col" as the base collection name if we have nothing left
253 if (name_buffer.length() == 0) {
254 name_buffer = new StringBuffer("col");
255 }
256
257 // Remote collections that aren't shared have the user's username prefixed to the collection name
258 if (Gatherer.isGsdlRemote && personal_collection_button.isSelected()) {
259 name_buffer = new StringBuffer(RemoteGreenstoneServer.getUsername() + "-" + name_buffer.toString());
260 }
261
262 // We need to ensure the filename is unique
263 int counter = 0;
264 StringBuffer new_name_buffer = new StringBuffer(name_buffer.toString());
265 while(filenameClashes(new_name_buffer.toString())) {
266 new_name_buffer = new StringBuffer(name_buffer.toString());
267 counter++;
268 String suffix = String.valueOf(counter);
269 // If we have to truncate the namestring so as to fit the suffix
270 if(suffix.length() + new_name_buffer.length() > 8) {
271 new_name_buffer.replace(new_name_buffer.length() - suffix.length(), new_name_buffer.length(), suffix);
272 }
273 // Or just append it if that isn't necessary
274 else {
275 new_name_buffer.append(suffix);
276 }
277 }
278
279 // All done
280 return new_name_buffer.toString();
281 }
282
283 private boolean filenameClashes(String filename)
284 {
285 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
286 File children[] = collect_directory.listFiles();
287 for(int i = 0; children != null && i < children.length; i++) {
288 if(children[i].getName().equals(filename)) {
289 return true;
290 }
291 }
292 return false;
293 }
294
295 public String getTitle() {
296 return title_final;
297 }
298
299 private void addCollectionsToModel(Vector base_collection_model, File collect_directory, String site) {
300 File[] possible_collections = collect_directory.listFiles();
301 String file_name = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
302 for (int i = 0; possible_collections != null && i < possible_collections.length; i++) {
303 // If the directory has a etc/collect.cfg file then it looks like a collection
304 File collect_cfg_file = new File(possible_collections[i], file_name);
305 if (collect_cfg_file.exists()) {
306 // If the directory has a metadata/ then the collection can be used as a base
307 File metadata_directory = new File(possible_collections[i], "metadata");
308 if (metadata_directory.exists()) {
309 // Add to model
310 BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
311 if (Gatherer.GS3 && site != null) {
312 collect_cfg.setSite(site);
313 }
314 Item item = new Item(possible_collections[i], collect_cfg);
315 if (!base_collection_model.contains(item)) {
316 base_collection_model.add(item);
317 }
318 }
319 }
320 }
321
322 }
323
324 private class CancelListener
325 implements ActionListener {
326 public void actionPerformed(ActionEvent event) {
327 cancelled = true;
328 self.dispose();
329 }
330 }
331
332
333 private class CreateListener
334 implements ActionListener {
335
336 public void actionPerformed(ActionEvent event) {
337 // Validate.
338 title_final = title.getText();
339 if(title_final.length() == 0) {
340 JOptionPane jOptionPane=new JOptionPane();
341 jOptionPane.setOpaque(!Utility.isMac());
342 jOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Error"), Dictionary.get("NewCollectionPrompt.Error"), JOptionPane.ERROR_MESSAGE);
343 return;
344 }
345 // 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
346 else {
347 if(titleClashes(title_final, null)) {
348 JOptionPane jOptionPane=new JOptionPane();
349 jOptionPane.setOpaque(!Utility.isMac());
350 if (jOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("NewCollectionPrompt.Title_Clash"), Dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
351 return;
352 }
353 }
354 }
355
356 description_final = description.getText();
357
358 // If we got this far there are no errors.
359 Item item_final = (Item) base_collection.getSelectedItem();
360 base_final = item_final.getFile();
361
362 cancelled = false;
363
364 self.dispose();
365 }
366 }
367
368 private class DescriptionListener
369 extends KeyAdapter {
370 public void keyPressed(KeyEvent event) {
371 if(event.getKeyCode() == KeyEvent.VK_TAB) {
372 event.consume();
373 base_collection.grabFocus();
374 }
375 }
376 }
377
378 private class Item
379 implements Comparable {
380 private BasicCollectionConfiguration config;
381 private File file;
382 private String name;
383 public Item(File file, BasicCollectionConfiguration config) {
384 this.config = config;
385 this.file = file;
386 this.name = null;
387 }
388 public Item(File file, String name) {
389 this.config = null;
390 this.file = file;
391 this.name = name;
392 }
393 public int compareTo(Object other) {
394 return toString().toLowerCase().compareTo(other.toString().toLowerCase());
395 }
396 public boolean equals(Object other) {
397 return compareTo(other) == 0;
398 }
399 public File getFile() {
400 return file;
401 }
402 public String toString() {
403 if(name == null && config != null) {
404 name = config.toString();
405 }
406 return name;
407 }
408 }
409}
410
411
412
Note: See TracBrowser for help on using the repository browser.