KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > directory > jxplorer > LdifExport


1 package com.ca.directory.jxplorer;
2
3 import java.awt.*;
4 import java.util.*;
5 import java.util.logging.Logger JavaDoc;
6 import java.util.logging.Level JavaDoc;
7 import java.io.*;
8 import javax.swing.*;
9
10 import javax.naming.*;
11 import javax.naming.directory.*;
12
13 import com.ca.directory.jxplorer.tree.*;
14 import com.ca.directory.jxplorer.broker.*;
15 import com.ca.commons.naming.*;
16 import com.ca.commons.cbutil.*;
17
18 public class LdifExport extends CBDialog
19 {
20     JTextArea rootDN, newRootDN;
21     DataSource dataSource;
22     SmartTree searchTree;
23     SmartTree schemaTree;
24
25     FileWriter saveFile;
26     LdifUtility ldifutil = new LdifUtility();
27
28     boolean usingSearch;
29
30     CBpbar pbar; // shows how far an operation has progressed for large ops.
31

32     static String JavaDoc lastDirectory = null;
33
34     private static Logger JavaDoc log = Logger.getLogger(LdifExport.class.getName());
35
36     /**
37      * Constructor for the LdifExport window. Takes a DN, and
38      * a jndi broker. If it is exporting from a search result
39      * set, it takes the search tree as a parameter, and a boolean
40      * flag specifying that the tree should be used to list the DNs
41      * to be exported; otherwise it does a full dump from the provided
42      * DN.<p>
43      *
44      * The constructor sets up the GUI, defining buttons and fields
45      * and registering button listeners.
46      *
47      * @param D the base DN to work from
48      * @param broker the jndi broker to use to read entry attribtues from,
49      * and to physically write the ldif file
50      * @param searchTree (possibly) a tree containing a list of search
51      * results, to be used if the search flag is set
52      * @param usingSearch a boolean flag that forces the reading of the
53      * list of DNs to save from the tree, rather than
54      * directly from the directory...
55      */

56     public LdifExport(DN D, DataSource broker, SmartTree searchTree, boolean usingSearch, Frame owner)
57     {
58         this(D, broker, searchTree, usingSearch, owner, HelpIDs.LDIF_EXPORT_TREE);
59     }
60
61     /**
62      * Constructor for the LdifExport window. Takes a DN, and
63      * a jndi broker. If it is exporting from a search result
64      * set, it takes the search tree as a parameter, and a boolean
65      * flag specifying that the tree should be used to list the DNs
66      * to be exported; otherwise it does a full dump from the provided
67      * DN.<p>
68      *
69      * The constructor sets up the GUI, defining buttons and fields
70      * and registering button listeners.
71      *
72      * @param D the base DN to work from
73      * @param broker the jndi broker to use to read entry attribtues from,
74      * and to physically write the ldif file
75      * @param searchTree (possibly) a tree containing a list of search
76      * results, to be used if the search flag is set
77      * @param usingSearch a boolean flag that forces the reading of the
78      * list of DNs to save from the tree, rather than
79      * directly from the directory...
80      * @param helpID the ID of the help page to attach to the Help button.
81      */

82     public LdifExport(DN D, DataSource broker, SmartTree searchTree, boolean usingSearch, Frame owner, String JavaDoc helpID)
83     {
84         super(owner, CBIntText.get("LDIF Export"), helpID);
85
86         OK.setToolTipText(CBIntText.get("Perform the LDIF export"));
87         Cancel.setToolTipText(CBIntText.get("Cancel without performing an LDIF export"));
88         Help.setToolTipText(CBIntText.get("Display help about LDIF exporting"));
89
90         if (D==null) D = new DN();
91
92         this.dataSource = broker;
93         this.searchTree = searchTree;
94         this.usingSearch = usingSearch;
95
96         display.add(new JLabel(CBIntText.get("Root DN")),0,0);
97
98         display.makeHeavy();
99
100         rootDN = new JTextArea(D.toString());
101         rootDN.setLineWrap(true); //TE: allows line wrapping.
102
display.add(new JScrollPane(rootDN, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),1,0); //TE: scroll pane that scrolls vertically on need and never scrolls horizontally.
103

104         display.makeLight();
105
106         display.add(new JLabel(CBIntText.get("New root DN")),0,1);
107
108         display.makeHeavy();
109         newRootDN = new JTextArea(D.toString());
110         newRootDN.setLineWrap(true); //TE: allows line wrapping.
111
display.add(new JScrollPane(newRootDN, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),1,1); //TE: scroll pane that scrolls vertically on need and never scrolls horizontally.
112

113         display.makeLight();
114     }
115
116     /**
117     * A quick spot of mucking around to add '.ldif' to naked files.
118     *
119     */

120
121     protected File adjustFileName(File readFile)
122     {
123         if (readFile == null) return null; // sanity check
124

125         if (readFile.exists()) return readFile; // don't do anything if file already exists...
126

127         String JavaDoc name = readFile.getName();
128         if (name.indexOf('.') != -1) return readFile; // ... or if it already has an extension.
129

130         name = name + ".ldif";
131
132         return new File(readFile.getParentFile(), name);
133     }
134
135     /**
136      * This method is called by the base class when the OK button is pressed.
137      * Handles actually writing the ldif file (relying heavily on LdifUtility for
138      * the grunt work). Does the actual file writing in a separate thread.
139      */

140
141     public void doOK()
142     {
143         if(!checkRootDN()) //TE: bug 5057.
144
return;
145
146         setVisible(false);
147
148         JFileChooser chooser = new JFileChooser(JXplorer.getProperty("ldif.homeDir"));
149
150         chooser.addChoosableFileFilter(new CBFileFilter(new String JavaDoc[] {"ldif", "ldi"},"Ldif Files (*.ldif, *.ldi)"));
151
152         int option = chooser.showSaveDialog(this);
153
154         if (option == JFileChooser.APPROVE_OPTION) // only do something if user chose 'ok'
155
{
156             File readFile = chooser.getSelectedFile();
157             if (readFile == null)
158             {
159                 CBUtility.error(CBIntText.get("Please select a file"));
160             }
161             else
162             {
163                 readFile = adjustFileName(readFile); // whack an '.ldif' on the end if necessary.
164

165                 int response = -1;
166                 if (readFile.exists()) //TE: ask the user if they want to overwrite an existing file.
167
{
168                     response = JOptionPane.showConfirmDialog(this, CBIntText.get("File ''{0}'' already exsists. Do you want to replace it?", new String JavaDoc[] {readFile.toString()}),
169                                         CBIntText.get("Overwrite Confirmation"), JOptionPane.YES_NO_OPTION );
170
171                     if (response != JOptionPane.YES_OPTION)
172                     {
173                         setVisible(true);
174                         return;
175                     }
176                 }
177
178                 JXplorer.setProperty("ldif.homeDir", readFile.getParent());
179                 doFileWrite(readFile);
180             }
181         }
182     }
183
184     /**
185      * Does three checks.<br><br>
186      * 1) if there is a root DN and a new root DN. If not a confirmation message appears
187      * asking if the user wants to export the full subtree.<br>
188      * 2) if there is no root DN. In this case a dialog appears asking for it.
189      * 3) if there is no new root DN. In this case a dialog appears asking for it.
190      * @return true only if all the checks succeed (or user approves the export full subtree).
191      */

192     public boolean checkRootDN()
193     {
194         String JavaDoc oldRoot = (rootDN.getText()).trim(); // the original DN
195
String JavaDoc newRoot = (newRootDN.getText()).trim(); // the replacement DN (may be identical!)
196

197         if((oldRoot == null || oldRoot.length() <= 0) && (newRoot == null || newRoot.length() <= 0))
198         {
199             int response = JOptionPane.showConfirmDialog(this, CBIntText.get("Without a 'Root DN' and a 'New Root DN', the full tree will be exported. Do you want to continue?"),
200                                 CBIntText.get("Export Full Tree"), JOptionPane.YES_NO_OPTION );
201             if (response != JOptionPane.YES_OPTION)
202                 return false;
203
204             return true;
205         }
206         else if(oldRoot == null || oldRoot.length() <= 0)
207         {
208             JOptionPane.showMessageDialog(this, CBIntText.get("Please enter a 'Root DN'."),
209                                             CBIntText.get("Root DN"), JOptionPane.INFORMATION_MESSAGE );
210             return false;
211
212         }
213         else if(newRoot == null || newRoot.length() <= 0)
214         {
215             JOptionPane.showMessageDialog(this, CBIntText.get("Please enter a 'New Root DN'."),
216                                             CBIntText.get("New Root DN"), JOptionPane.INFORMATION_MESSAGE );
217             return false;
218         }
219
220         return true;
221     }
222
223
224     /**
225      * Launch a DataQuery that will write the ldif file.
226      *
227      */

228     protected void doFileWrite(File saveFile)
229     {
230         if (saveFile == null)
231             CBUtility.error(CBIntText.get("Unable to write to empty file"), null);
232
233         final File myFile = saveFile;
234
235         dataSource.extendedRequest(new DataQuery(DataQuery.EXTENDED)
236         {
237             public void doExtendedRequest(Broker b)
238             {
239                 try
240                 {
241                     FileWriter myFileWriter = new FileWriter(myFile);
242
243                     pbar = new CBpbar(LdifExport.this, CBIntText.get("Saving LDIF file"), CBIntText.get("Saving Data"));
244
245 //XXX SCHEMA-FIX; what's happening here? if (b instanceof SchemaBroker)
246
// ((SchemaBroker)b).setRaw(true);
247

248                     myFileWriter.write("version: 1\n");
249
250                     DN oldRoot = new DN(rootDN.getText()); // the original DN
251
DN newRoot = new DN(newRootDN.getText()); // the replacement DN (may be identical!)
252

253                     if (usingSearch)
254                     {
255                         Vector bloop = searchTree.getAllNodes(new DN(rootDN.getText()));
256                         saveLdifList(bloop, myFileWriter, oldRoot.toString(), newRoot.toString(), b);
257                     }
258                     else
259                     {
260                         saveLdifTree(oldRoot, myFileWriter, oldRoot.toString(), newRoot.toString(), b);
261                     }
262
263                     //TE: this seems to resolve the problem of no being able to access the ldif file until
264
//TE: focus is moved from the current DN or the user exits JX. See Bug numbers 669 & 533.
265
//TE: NOTE: this fix could be the cause of an 'Extended' error...not sure!
266
myFileWriter.close();
267                 }
268                 catch (Exception JavaDoc e)
269                 {
270                     setException(e);
271                 }
272
273 //XXX if (b instanceof SchemaBroker)
274
// ((SchemaBroker)b).setRaw(false);
275

276                 if(pbar.isCanceled()) //TE: delete the file if the user cancels the export.
277
myFile.delete();
278
279                 closeDown();
280                 return;
281             }
282         });
283     }
284
285
286
287     /**
288      * Write a subtree to an ldif file by recursing through the
289      * tree, calling saveLdifEntry as it goes...
290      *
291      * @param treeApex the root node of the sub tree to be written out.
292      * @param saveFile the file being written to...
293      * @param origPrefix the original DN prefix, that may be modified
294      * on write to be replacementPrefix. This may be
295      * null if no action is to be taken.
296      * @param newPrefix another DN to replace the originalPrefix.
297      * @return number of entries written
298      */

299
300     public boolean saveLdifTree(DN treeApex, FileWriter saveFile, String JavaDoc origPrefix, String JavaDoc newPrefix, Broker broker)
301     {
302         // sanity checks...
303
if (treeApex==null) return false;
304         if (pbar == null) return false;
305
306         if (newPrefix==null) origPrefix = null; // sanity check
307
if ((origPrefix!=null)&&(origPrefix.equals(newPrefix))) // sanity check
308
{origPrefix = null; newPrefix = null; }
309
310         if (pbar.isCanceled()) return false; // user canceled
311

312         Attributes atts = null;
313
314         try
315         {
316             if (treeApex.isEmpty() == false)
317             {
318                 atts = broker.unthreadedReadEntry(treeApex, null);
319             }
320
321             if (atts != null)
322             {
323                 DN escapeMe = new DN(treeApex);
324                 ldifutil.writeLdifEntry(escapeMe.toString(), saveFile, origPrefix, newPrefix, atts); // save the current dn...
325
}
326             // need to get this as a DXNamingEnumeration to set progress bar...
327
DXNamingEnumeration children = broker.unthreadedList(treeApex);
328
329             pbar.push(children.size()); // might be zero...
330

331             while (children != null && children.hasMore())
332             {
333                 String JavaDoc subDNString = ((NameClassPair)children.next()).getName();
334                 DN child = new DN(treeApex); // this could be done by string manip.,
335
DN subDN = new DN(subDNString);
336                 child.addChildRDN(subDN.getLowestRDN()); // but then what happens if DN naming changes?
337

338                 if (saveLdifTree(child, saveFile, origPrefix, newPrefix, broker)==false) // recursively traverse tree and write data
339
return false;
340             }
341         }
342         catch (NamingException e)
343         {
344             CBUtility.error(this, CBIntText.get("Unable to read dn: {0} from directory", new String JavaDoc[] {treeApex.toString()}), e);
345         }
346         catch (Exception JavaDoc e)
347         {
348             CBUtility.error(this, CBIntText.get("General error reading dn: {0} from directory", new String JavaDoc[] {treeApex.toString()}), e);
349             e.printStackTrace();
350         }
351
352         pbar.pop();
353         pbar.inc();
354
355         return true;
356     }
357
358     /**
359      * Writes a list of entries to an ldif file.
360      *
361      * @param dns the list of the dns of objects to write out...
362      * @param saveFile the file being written to...
363      * @param originalPrefix the original DN prefix, that may be modified
364      * on write to be replacementPrefix. This may be
365      * null if no action is to be taken.
366      * @param replacementPrefix another DN to replace the originalPrefix.
367      */

368
369     public void saveLdifList(Vector dns, FileWriter saveFile, String JavaDoc originalPrefix, String JavaDoc replacementPrefix, Broker broker)
370     {
371         if (replacementPrefix==null) originalPrefix = null; // sanity check.
372
if ((originalPrefix!=null)&&(originalPrefix.equals(replacementPrefix))) // sanity check.
373
{
374             originalPrefix = null;
375             replacementPrefix = null;
376         }
377         int size = dns.size();
378         pbar.push(size);
379
380         for (int i=0; i<size; i++)
381         {
382             DN dn = (DN)dns.elementAt(i);
383
384             try
385             {
386                 Attributes atts = broker.unthreadedReadEntry(dn, null);
387                 ldifutil.writeLdifEntry(dn.toString(), saveFile, originalPrefix, replacementPrefix, atts);
388             }
389             catch (NamingException e)
390             {
391                 log.log(Level.WARNING, "Unable to read dn: '" + dn.toString() + "' from directory ", e);
392             }
393             catch (Exception JavaDoc e)
394             {
395                 log.log(Level.WARNING, "General error reading: dn: '" + dn.toString() + "' from directory ", e);
396             }
397
398             if (pbar.isCanceled()) return;
399             pbar.inc();
400         }
401         pbar.close(); // no need to pop out; we're done...
402
}
403
404     private void closeDown()
405     {
406         try
407         {
408             if (saveFile != null) saveFile.close();//TE: Always == null!
409
log.warning("Closed LDIF file");
410         }
411         catch (IOException e) {;}
412
413         if (pbar != null) pbar.close();
414         setVisible(false);
415         dispose();
416     }
417 }
Popular Tags