KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.ca.directory.jxplorer;
2
3 import com.ca.commons.cbutil.*;
4 import com.ca.commons.naming.*;
5 import com.ca.directory.jxplorer.broker.Broker;
6 import com.ca.directory.jxplorer.broker.SchemaBroker;
7 import com.ca.directory.jxplorer.tree.SmartTree;
8
9 import javax.naming.NamingException JavaDoc;
10 import javax.swing.*;
11 import java.awt.*;
12 import java.io.*;
13 import java.util.ArrayList JavaDoc;
14 import java.util.Enumeration JavaDoc;
15 import java.util.logging.Logger JavaDoc;
16
17 public class LdifImport //extends JDialog implements ActionListener
18
{
19     DataSource dataSource;
20     File readFile;
21     SmartTree tree;
22     Frame owner;
23     SchemaBroker schema;
24     boolean offline = true;
25     LdifUtility ldifutil = new LdifUtility();
26     
27     static final boolean debug = true;
28     
29     static ProgressMonitorInputStream pmonitor;
30
31     private static Logger JavaDoc log = Logger.getLogger(LdifImport.class.getName());
32
33     /**
34      * Constructor for the LdifImport window. Takes a DN, and
35      * a data modifier.<p>
36      *
37      * The constructor sets up the GUI, defining buttons and fields
38      * and registering button listeners.
39      *
40      * @param dataSource the base DN to work from
41      * @param mrTree the tree to display the read ldif entries in
42      * @param owner a parent frame to display the progress bar in
43      * @param schema schema, if available, to check whether attributes are binary or not
44      * (otherwise this may need to be inferred from the data)
45      */

46      
47     public LdifImport(DataSource dataSource, SmartTree mrTree, Frame owner, SchemaBroker schema)
48     {
49         this.owner = owner;
50     
51         this.schema = schema;
52         
53         tree = mrTree;
54         DN base = tree.getCurrentDN();
55         
56         offline = ((tree.getRootDN() == null) || (tree.getRootDN().toString().equals(SmartTree.NODATA)));
57         
58         if ((base==null)||(tree.getRootDN()==null)||(offline)) // check that we *have* a base, or if we're working
59
base = new DN(); // offline set it to blank anyway...
60

61         this.dataSource = dataSource;
62
63         openFile();
64     }
65
66
67     public void openFile()
68     {
69         JFileChooser chooser = new JFileChooser(JXplorer.getProperty("ldif.homeDir"));
70         chooser.addChoosableFileFilter(new CBFileFilter(new String JavaDoc[] {"ldif", "ldi"},"Ldif Files (*.ldif, *.ldi)"));
71         
72         int option = chooser.showOpenDialog(owner);
73         
74         if (option == JFileChooser.APPROVE_OPTION) // only do something if user chose 'ok'
75
{
76             readFile = chooser.getSelectedFile();
77             if (readFile == null)
78                 CBUtility.error(CBIntText.get("Please select a file"));
79             else
80             {
81                 JXplorer.setProperty("ldif.homeDir", chooser.getSelectedFile().getParent());
82                 ldifutil.setFileDir(chooser.getSelectedFile().getParent());
83                 doFileRead(readFile);
84             }
85
86             if(owner instanceof JXplorer && offline)
87             {
88                 ((JXplorer)owner).getMainMenu().setConnected(false);
89             }
90         }
91     }
92
93     protected void doFileRead(File readFile)
94     {
95         if (readFile == null)
96             CBUtility.error(CBIntText.get("unable to read null ldif file"), null);
97
98         final File myFile = readFile;
99
100         dataSource.extendedRequest(new DataQuery(DataQuery.EXTENDED)
101         {
102             public void doExtendedRequest(Broker b)
103             {
104                 try
105                 {
106                     FileInputStream rawBytes = new FileInputStream(myFile);
107                     pmonitor = new ProgressMonitorInputStream(owner, CBIntText.get("Reading ldif file"), rawBytes);
108                 }
109                 catch (FileNotFoundException e)
110                 {
111                     CBUtility.error(CBIntText.get("Unable to read the ldif file ''{0}''.", new String JavaDoc[] {myFile.toString()}), e);
112                     return;
113                 }
114
115                 readLdifTree("", pmonitor, "", "", b, this);
116
117                 if (b.getException() != null)
118                 {
119                     CBUtility.error(CBIntText.get("There were one or more errors reading the ldif file\n(See the log for more details)"), b.getException());
120                     b.clearException();
121                 }
122                 closeDown();
123             }
124         });
125         
126     }
127
128     
129     /**
130      * Read a subtree from an ldif file, adding entries as
131      * they are read...
132      *
133      * @param treeApex the root node of the sub tree to be written out.
134      * @param textStream The stream being read (i.e. the ldif file)
135      * @param origPrefix the original DN prefix, that may be modified
136      * on write to be replacementPrefix. This may be
137      * null if no action is to be taken.
138      * @param newPrefix another DN to replace the originalPrefix.
139      * @param b the broker to send the read data to
140      * @param query the DataQuery doing the import
141      */

142     
143     public void readLdifTree(String JavaDoc treeApex, InputStream textStream, String JavaDoc origPrefix, String JavaDoc newPrefix, Broker b, DataQuery query)
144     {
145         DN newDN = null; // a DN to be added to be read from the data source
146

147         DXEntry apex = null; // the top of the ldif tree in this file
148

149         if (origPrefix == null) origPrefix = "";
150
151         int numEntriesRead = 0;
152
153         if (newPrefix==null) origPrefix = null; // sanity check
154
if ((origPrefix!=null)&&(origPrefix.equals(newPrefix))) // sanity check
155
{origPrefix = null; newPrefix = null; }
156
157         //XXX hack alert: in fact DN comparision is a lot more restictive than what we do here.
158
//XXX
159
treeApex = treeApex.toLowerCase();
160
161         BufferedReader readText = null;
162         try
163         {
164              readText = new BufferedReader(new InputStreamReader(textStream, "UTF-8"));
165         }
166         catch (UnsupportedEncodingException e)
167         {
168             CBUtility.error(CBIntText.get("Unexpected problem - Unable to read the ldif file-not utf8 reader available "), e);
169             return;
170         }
171
172
173         DXEntry newEntry = null; // object to place newly read entry info in
174
String JavaDoc line =""; // the first line read from the ldif file
175

176         try
177         {
178             // start things rolling...
179
readText.mark(256); // prepare to read a 'version: X' header...
180
line = readText.readLine(); // read the version header
181
if (line.toLowerCase().startsWith("version") == false) // version headers are kinda
182
{ // optionalish: this might not be one.
183
//log.warning("Warning: ldif file does not start with 'version ...'");
184
readText.reset();
185             }
186
187             ArrayList JavaDoc list = new ArrayList JavaDoc(); //TE: stores the root DN('s ).
188

189             try
190             {
191                 while (((newEntry = ldifutil.readLdifEntry(readText))!=null))
192                 {
193                     if (query.isCancelled()) return; // check whether the user has cancelled this query.
194

195                     int size = newEntry.getDN().size();
196
197                     if (size != 0)
198                     {
199                         newDN = newEntry.getDN();
200
201                         if (apex == null || apex.getDN().size() > size)
202                         {
203                             apex = newEntry; // keep track of top entry...
204
}
205                         translateToUnicode(newEntry);
206                         b.unthreadedModify(null, newEntry);
207
208                         if (!list.contains(getRoot(b, newDN)))
209                             list.add(getRoot(b, newDN));
210                     }
211                     else
212                     {
213                         log.warning("skipping ldif entry with no dn: ");
214                     }
215
216                     pmonitor.getProgressMonitor().setNote(CBIntText.get("reading entry # ") + (++numEntriesRead)); // XXX I'm not translating this to the MessageFormat version of CBIntText.get because I'm worried about performance - CB
217
}
218             }
219             catch (InterruptedIOException e) // almost certainly the user hitting 'cancel' on the progress bar
220
{
221                 return;
222             }
223             catch (IOException e2) // some other file reading error
224
{
225                 CBUtility.error(CBIntText.get("unable to read ldif file"), e2);
226                 return;
227             }
228             catch (NamingException JavaDoc e)
229             {
230                 //TE: bug: 5153. Not sure if this should be caught here and stop or should it try to process the rest of the LDIF file?
231
CBUtility.error(CBIntText.get("An error occured while processing the LDIF file: "), e);
232                 return;
233             }
234
235
236             // quicky check to see if we're working off line, or need to set the
237
// root for some other reason (can't actually think of any...)
238

239             if ((tree.getRootDN()==null)||(tree.getRootDN().toString().equals(SmartTree.NODATA)))
240             {
241                 //TE: if there are multiple root DNs this ensures that they are displayed (see bug 529),
242
// e.g o=CA1 & o=CA2.
243
// However, I have a feeling this could make other things fall over...but have no idea
244
// what at this stage because this only keeps account of the last root DN (e.g. o=CA2)
245
// whereas there may be several...
246
for(int i=0;i<list.size();i++)
247                 {
248                     String JavaDoc root = (list.get(i)).toString();
249
250                     tree.setRoot(root); // bit of a hack; pass the last known real DN
251
tree.getRootNode().setStructural(true);
252                 }
253             }
254
255             // give the tree a kick to make it refresh the apex parent, thus displaying
256
// the newly imported nodes.
257
if (apex != null && apex.getDN() != null && apex.getDN().size() > 1)
258                 tree.refresh(apex.getDN().parentDN());
259         }
260         catch (IOException e)
261         {
262             log.warning("Unable to read file " + readFile.toString());
263         }
264
265         catch (Exception JavaDoc e2)
266         {
267             log.warning("error parsing file " + readFile.toString());
268             log.warning("Error occured reading line: " + ((line==null)?"*null line*":line) + "\n (debug info: err was : " + e2 + "\n ");
269             e2.printStackTrace();
270         }
271
272     }
273
274     private String JavaDoc getRoot(Broker b, DN lastKnownDN)
275     {
276         if (b==null)
277         {
278             log.warning("error: no data source available in ldif import/view");
279             return null;
280         }
281
282         if (lastKnownDN == null)
283         {
284             log.warning("error: no DN available in ldif import/view");
285             return null;
286         }
287
288         DN root = lastKnownDN;
289         DN test = root;
290
291         /*
292          * Go up through parents until we find a parent not in
293          * database; then the current value is the highest DN and
294          * hence root! ( A bit hacky, but it works!)
295          */

296         try
297         {
298             while (root != null || (root.size()>0))
299             {
300                 test = root.parentDN();
301                 if ((test==null)||(b.unthreadedExists(test)==false)||test.size()==0)
302                     return root.toString();
303                 root = test;
304             }
305         }
306         catch (NamingException JavaDoc e)
307         {
308             log.warning("Error testing root node " + test + "\n" + e );
309         }
310         log.warning("Unable to determine root node from " + lastKnownDN);
311         return null; // should never be reached
312
}
313     
314     
315     private void closeDown()
316     {
317         try
318         {
319             if (pmonitor != null) pmonitor.close();
320         }
321         catch (IOException e) {;}
322 // setVisible(false);
323
// tree.collapse();
324
// dispose();
325
}
326     
327     /**
328      * If schema broker is active, use schema to check whether
329      * we have a utf-8 encoded unicode string. If we do, decode
330      * it. If schema is not active, use heuristic to check if
331      * binary thingumy is utf-8, and if it is, translate it anyway.
332      */

333      
334     private void translateToUnicode(DXEntry entry)
335     {
336         if (offline == false) return; // we only need to do this when working offline -
337
// otherwise we can pass utf8 straight through to
338
// the directory and everything will still magically
339
// work...
340
try
341         {
342             Enumeration JavaDoc atts = entry.getAll();
343             while (atts.hasMoreElements())
344             {
345                 DXAttribute att = (DXAttribute)atts.nextElement();
346                 for (int i=0; i<att.size(); i++)
347                 {
348                     if (att.get(i) instanceof String JavaDoc == false)
349                     {
350                         byte[] seq = (byte[]) att.get(i);
351                          
352                         if (CBParse.isUTF8(seq)) // guess whether it is utf8...
353
{
354                             try
355                             {
356                                 String JavaDoc s = new String JavaDoc(seq, "UTF8");
357                                 att.remove(i);
358                                 att.add(i, s);
359                                 att.setString(true); // is honest unicode string, not really nasty binary...
360
}
361                             catch (Exception JavaDoc e)
362                             {
363                                 log.warning("couldn't convert: " + att.getID() + "\n " + e);
364                             }
365                         }
366                     }
367                 }
368             }
369         }
370         catch (NamingException JavaDoc e)
371         {
372             // ignore ubiquitous naming exception
373
}
374     }
375 /*
376     boolean isStringInSchema()
377     {
378         return false;
379     }
380 */

381 }
Popular Tags