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

Last change on this file since 12498 was 12300, checked in by kjdon, 18 years ago

removed some unused variables

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