source: main/trunk/gli/src/org/greenstone/gatherer/collection/CollectionTreeNode.java@ 23433

Last change on this file since 23433 was 23433, checked in by ak19, 13 years ago

GLI now has a gs.FilenameEncoding metadata field which appears like all the others in GLI's EnrichPane, but is unique in that this metadata (once set, changed or removed) must be applied to the affected filenames in the Collection Tree. More importantly, the changes made for this are to allow GLI's java code to interact with the recent changes to Perl where strings were made unicode-aware (for proper regex matching) but which required other changes elsewhere. To still support filenames with different encodings Perl used URL encoded versions of filenames representing characters' code point values in URL encoding. This required that GLI write out URL encoded filenames to the metadata.xml files that are associated with each folder level of a collection, so that Perl can read them. In this way, they can both speak of the same filenames. Only works on unicode 16 (such as latin-1), non-UTF8 systems. The latter is a requirement since Java uses the filesystem encoding from startup. If it is UTF8, non-recognised characters are replaced by the invalid char for UTF8. This process being destructive, we can't get the original filenames' bytecodes back. The changes made to GLI will work on Windows which is UTF-16 (windows codepage 1252), presumably also Macs (some kind of UTF-16) and also works on Native Latin 1 Linux systems. UTF-8 Linux systems need to be reconfigured to Native Latin-1, or if not installed, an administrator can install it easily.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2004 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.collection;
28
29
30import java.io.*;
31import javax.swing.*;
32import org.greenstone.gatherer.cdm.CollectionDesignManager;
33import org.greenstone.gatherer.file.FileNode;
34import org.greenstone.gatherer.metadata.FilenameEncoding;
35import org.greenstone.gatherer.util.JarTools;
36import java.util.Set;
37import java.util.Iterator;
38
39
40/** This class represents one node in the collection tree. */
41public class CollectionTreeNode
42 extends FileNode
43{
44 static final public ImageIcon GREEN_FILE_ICON = JarTools.getImage("greenfile.gif", true);
45
46 /** Is this file a metadata database that is explodable with the explode_metadata_databases.pl script? */
47 private boolean is_explodable = false;
48
49 /** Keeps track of whether this file can be replaced with a Greenstone-generated html file.
50 * To work with replace_srcdoc_with_html.pl */
51 private boolean is_srcreplaceable = false;
52
53 public CollectionTreeNode(File file)
54 {
55 super(file);
56 // the super call will additionally call calcDisplayString() which will get any
57 // applicable the filename encoding and apply it to the file's name for display.
58
59 this.is_explodable = CollectionDesignManager.plugin_manager.isFileExplodable(file);
60 // To work with replace_srcdoc_with_html.pl
61 this.is_srcreplaceable = CollectionDesignManager.plugin_manager.isFileSrcReplaceable(file);
62
63 }
64
65
66 public FileNode addChildNode(File file)
67 {
68 CollectionTreeNode child_node = new CollectionTreeNode(file);
69 child_node.setModel(model);
70 child_node.setParent(this);
71 return child_node;
72 }
73
74
75 public boolean isExplodable()
76 {
77 return is_explodable;
78 }
79
80 // To work with replace_srcdoc_with_html.pl
81 public boolean isSrcReplaceable()
82 {
83 return is_srcreplaceable;
84 }
85
86 /** This method returns a string representation of the filenodes in the
87 * <i>Collection</i> Tree, that can then be displayed in the tree. If the
88 * filename encoding is specified as metadata with the file, then this
89 * method will apply that to the filename's bytes to get the displayName.
90 */
91 protected String calcDisplayString() {
92 // metadata.xml files in collections don't get displayed anyway
93 if(file.getName().equals("metadata.xml")) {
94 return super.calcDisplayString();
95 }
96
97 if(!FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED) {
98 return super.calcDisplayString();
99 }
100
101 // Else: try to encode the display string from the
102 // file_to_encoding map. If that fails, just use the locale
103 String displayName = null;
104 String urlEncodedPath = getURLEncodedFilePath();
105 String encoding = FilenameEncoding.findFilenameEncoding(file, urlEncodedPath, false);
106
107 // if it isn't the same as the current encoding already applied, reapply
108 // it which will set the filenameEncoding again as well
109 if(!encoding.equals(getFilenameEncoding())) {
110 displayName = reencodeDisplayName(encoding); // may return null
111 }
112
113 if(displayName == null) {
114 if(FilenameEncoding.DEBUGGING) {
115 displayName = getURLEncodedFileName();
116 } else {
117 displayName = super.calcDisplayString();
118 }
119 }
120
121 return displayName;
122 }
123
124 /** Call this if the filename encoding has changed and needs to be
125 * recalculated and re-applied to the filename. This is only for display,
126 * so it only gets applied to the urlEncodedFileName (not urlEncodedFilePath).
127 * Note that the filenameEncoding may not be the same as the given encoding
128 * at the end of this method (in case it was a charset alias of the encoding).
129 * This method both sets and returns the displayFileName member variable.
130 * @return the reencoded display name, if the encoding was a recognised alias
131 * in which case the filenameEncoding will store the canonical name. */
132 public String reencodeDisplayName(String encoding) {
133 if(!FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED) {
134 return displayFileName; // may still be null
135 }
136
137 filenameEncoding = encoding; // clear previous value
138
139 if(filenameEncoding.equals("")) {
140 displayFileName = super.calcDisplayString(); // *FileNode* calcDisplayString
141 return displayFileName;
142 }
143
144 try{
145 displayFileName = new String(file.getName().getBytes(), filenameEncoding);
146 } catch(Exception e) {
147 // IllegalCharsetName-, UnsupportedCharset- or UnsupportedEncoding-Exception
148 // Store the unsupported encoding, but display with filesystem (or URL) encoding
149 filenameEncoding = encoding;
150
151 if(FilenameEncoding.DEBUGGING) {
152 displayFileName = getURLEncodedFileName();
153 } else {
154 displayFileName = super.calcDisplayString();
155 }
156 }
157 return displayFileName;
158 }
159
160 /** Can call this upon refreshing a FileNode (this CollectionTreeNode). It makes
161 * sure the display names of the visible nodes in the CollectionTree aren't stale */
162 public void refreshDescendantEncodings() {
163 // now recalculate encodings for all visible children
164
165 // Don't bother with the encoding stuff when multiple filename encodings
166 // are not supported because the system is UTF-8 (not Native-Latin-1) and
167 // Java interprets all filename bytes as UTF-8, which destructively
168 // converts unrecognised characters (for UTF-8) into the invalid character.
169
170 if(!FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED
171 || child_nodes == null)
172 {
173 return;
174 }
175
176 // get and apply the filename encoding, if any
177 for(int i = 0; i < child_nodes.size(); i++) {
178 CollectionTreeNode child_node = (CollectionTreeNode) child_nodes.get(i);
179 String urlEncodedPath = child_node.getURLEncodedFilePath();
180
181 String encoding = FilenameEncoding.findFilenameEncoding(
182 child_node.getFile(), urlEncodedPath, false);
183
184 // if current encoding is different from the existing one, re-apply encoding
185 if(!child_node.getFilenameEncoding().equals(encoding)) {
186 child_node.reencodeDisplayName(encoding);
187 }
188 }
189 }
190
191 // Unused at present
192 /** Call when the filename encoding of this folder level fileNode has changed
193 * and therefore the filename encodings of the descendant fileNodes have to be
194 * reset (their entries in the file_to_encoding hashmap cleared), so that we know
195 * to recalculate these later. Call when deleting, moving or renaming col nodes */
196 public void resetDescendantEncodings() {
197 if(FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED) {
198 resetDescendantEncodings(this.file, this.getURLEncodedFilePath());
199
200 // for an actual file/folder delete, want to remove all corresponding
201 // entries from the hashtable without recalculating any encodings
202 // (files have been deleted, so no there will be no filenames to display).
203 // So don't do this here: refreshDescendantEncodings();
204 // It's done near the end of FileNode.map().
205 }
206 }
207
208 // Together with the above, unused at present
209 private static void resetDescendantEncodings(File f, String urlEncodedPath)
210 {
211 // remove this file f's urlencoded path name from the file_to_encoding Map
212 FilenameEncoding.map.remove(urlEncodedPath);
213
214 if(f.isDirectory()) {
215 File[] children = f.listFiles();
216 for(int i = 0; i < children.length; i++) {
217 urlEncodedPath = FilenameEncoding.fileToURLEncoding(children[i]);
218 resetDescendantEncodings(children[i], urlEncodedPath);
219 // sets filenameEncoding var
220 }
221 }
222 }
223
224}
Note: See TracBrowser for help on using the repository browser.