KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > directory > jxplorer > viewer > MyHTMLEditorKit


1 package com.ca.directory.jxplorer.viewer;
2
3
4 import javax.swing.text.*;
5 import javax.swing.text.html.*;
6 import javax.naming.directory.*;
7 import java.io.UnsupportedEncodingException JavaDoc;
8 import java.util.Enumeration JavaDoc;
9 import java.util.HashSet JavaDoc;
10 import java.util.logging.Logger JavaDoc;
11 import java.util.logging.Level JavaDoc;
12 import java.net.URLDecoder JavaDoc;
13 import com.ca.commons.naming.*;
14 import com.ca.commons.cbutil.*;
15
16 /**
17  * A collection of evil hacks to get inside the (*^^(&* HMTL Editor Kit
18  * Model, and disable the automated HTML form submission code, allowing
19  * us to intercept form submissions.
20  */

21 class MyFormView extends FormView
22 {
23     /**
24      * Name of the Submit button. This must be removed on form submit, so
25      * that it doesn't get added to the entry.
26      */

27     public static final String JavaDoc SUBMIT = "Submit";
28
29     HTMLTemplateDisplay templateDisplay;
30     
31     private static Logger JavaDoc log = Logger.getLogger(MyHTMLEditorKit.class.getName());
32
33 // int numberNamingValues; //TE: these four are used in setRDN...
34
// AttributeValue [] namingValues;
35

36     public MyFormView(Element elem, HTMLTemplateDisplay display)
37     {
38         super(elem);
39
40         templateDisplay = display;
41     }
42
43     /**
44      * This method is what all the fuss in this whole class is about. It over-rides the
45      * method in the standard class which would try to submit this to a web server, and
46      * instead we parse the form data and try to submit it to the directory. Pretty neat
47      * ay?
48      */

49      
50     protected void submitData(String JavaDoc data)
51     {
52         DXEntry oldEntry = templateDisplay.currentEntry; //TE: get the old entry (i.e its attributes & values).
53

54         log.finest("Entry before changes: " + oldEntry);
55
56         DN dn = oldEntry.getDN(); // Get the original DN
57
RDN rdn = new RDN(oldEntry.getRDN()); //TE: get the rdn of the old entry.
58

59         String JavaDoc [] namingTypes = rdn.getAtts(); // Read the list of RDN attribute types
60
String JavaDoc [] namingRawValues = rdn.getRawVals(); // and values
61
boolean nameChanged = false;
62     
63         DXEntry newEntry = parseData(data, oldEntry); //TE: make an entry with any changes that the user may have done (this entry doesn't have a dn yet).
64

65         // Must remove the Submit attr so that it doesn't get added...
66
newEntry.remove(SUBMIT);
67
68         log.finest("Entry after changes: " + newEntry);
69
70         if (newEntry == null) return; // Error!
71

72         try
73         {
74             String JavaDoc newName; // temporary variable.
75
for(int i=0;i<namingTypes.length;i++) //TE: make the rdn (the rdn might be multivalued...).
76
{
77                 // if we have an entry for one of the naming values...
78
Attribute namingAtt = newEntry.get(namingTypes[i]);
79
80                 if(namingAtt != null)
81                 {
82                     newName = (String JavaDoc)namingAtt.get(); // XXX - does this handle multi valued atts correctly?
83

84                     if (newName!=null) // no deleting of names in html templates!
85
{
86                         // CB: bug 5054 - handle pesky white space.
87
// ... trim off any white space, unless it is all white space in which case leave one
88
// singleton space, and update the entry object with the newly trimmed name.
89
if (newName.trim().equalsIgnoreCase(newName) == false)
90                         {
91                             newName = newName.trim();
92                             if (newName.length() == 0) newName = " ";
93                             namingAtt.remove(0);
94                             namingAtt.add(0, newName);
95                         }
96
97                         if (newName.equals(namingRawValues) == false)
98                         {
99                             nameChanged = true;
100                             rdn.setRawVal(newName, i);
101                         }
102                     }
103                 }
104             }
105         }
106         catch (Exception JavaDoc e) // shouldn't happen; old entry should have already been validated by this stage.
107
{
108             log.log(Level.WARNING, "error parsing entry name in HTMLEditorKit ", e);
109         }
110         
111         if (nameChanged)
112         {
113             DN newDN = new DN(dn); // get the dn of the old entry so the new rdn can be added to it.
114
newDN.setRDN(rdn, newDN.size()-1); // set the rdn in the old dn.
115
newEntry.setDN(newDN); // give the new entry the new DN....PHEW
116
}
117         else
118         {
119             newEntry.setDN(dn); // Name hasn't changed; reuse old one
120
}
121
122         Enumeration JavaDoc allOldAtts = oldEntry.getAll();
123         
124         // merge the old and the new, with the new getting any atts that appear in old
125
// but not yet in new. The idea here is to allow transparent passing through of
126
// 'hidden' attributes, that are not affected by the form.
127

128         while (allOldAtts.hasMoreElements())
129         {
130             Attribute att = (Attribute)allOldAtts.nextElement();
131             if (att.size() != 0)
132                 if (newEntry.get(att.getID()) == null)
133                 {
134                     newEntry.put(att);
135                 }
136         }
137
138         // make the modification request!
139

140
141         templateDisplay.currentDataSource.modifyEntry(oldEntry, newEntry);
142     }
143
144     /**
145      * Parses the form query data string, which is in standard html escaped
146      * format, and load the results into a new DXEntry.
147      *
148      * @param data the html form to parse
149      * @param oldEntry the original entry, required for long string handling.
150      * @return the newly parse entry, suitable for sending to the directory.
151      */

152      
153     public DXEntry parseData(String JavaDoc data, DXEntry oldEntry)
154     {
155         DXEntry newEntry = new DXEntry();
156        
157         HashSet JavaDoc forbiddenAttributes = null; // used to prevent very long strings breaking stuff.
158

159         int start=0;
160         int equalpos=0;
161         int end=0;
162         int length = data.length();
163
164         try
165         {
166             while (start < length)
167             {
168                 end = data.indexOf('&', start);
169                 if (end == -1) end = length;
170                 
171                 equalpos = data.indexOf('=', start);
172     
173                 String JavaDoc attribute = data.substring(start, equalpos);
174
175                 //TODO - remove this deprecated method. Use decode(str, enc) where enc is the page enc.
176
//TODO - figure out how to get the page's advertised encoding.
177
String JavaDoc value = URLDecoder.decode(data.substring(equalpos+1, end));//, "ISO-8859-1");
178
Object JavaDoc val = value;
179
180                 String JavaDoc stringVal = null;
181
182                 // special handling for (XXX single valued) binary attributes
183
if (templateDisplay.currentBinaryAttributes.contains(attribute.toLowerCase()))
184                 {
185                     Object JavaDoc original = null;
186                     String JavaDoc oldVal = null;
187                     Attribute binAtt = templateDisplay.currentEntry.get(attribute);
188                     if (binAtt != null && binAtt.size()>0)
189                     {
190                         original = binAtt.get();
191                         oldVal = CBBase64.binaryToString((byte[])original);
192                     }
193                     
194                     if (value.equals(oldVal))
195                     {
196                         val = original; // nothing has changed...
197
}
198                     else
199                     {
200                         // XXX Special handling for passwords: pass raw string through if password (only).
201
if (attribute.toLowerCase().indexOf("password") > -1)
202                         {
203                             try
204                             {
205                                 val = value.getBytes("UTF-8");
206                             }
207                             catch (UnsupportedEncodingException JavaDoc e2)
208                             {
209                                 CBUtility.error(templateDisplay, CBIntText.get("Unable to UTF-8 encode password"), e2);
210                             }
211                         }
212                         else
213                         {
214                             val = CBBase64.stringToBinary(value); // not password - back convert data.
215
}
216                     }
217                 }
218                 else if (attribute.toLowerCase().indexOf("address") > -1) // special handling for address fields...
219
{
220                     val = value.replace('\n','$');
221                 }
222                 
223                 if (val instanceof String JavaDoc)
224                     stringVal = (String JavaDoc)val;
225                     
226                 int dataLength = (stringVal != null)?stringVal.length():((byte[])val).length; // (*&^%*)( java array syntax.
227

228                 /*
229                  * If the attribute was an illegally long string, replace it
230                  * now with the original oldEntry attribute (thus preventing it
231                  * from being modified in the directory, as there will be no
232                  * change.) - also add this attribute to the 'forbidden atts'
233                  * list.
234                  */

235                  
236                 if (stringVal != null && stringVal.equals(HTMLTemplateDisplay.ILLEGAL_VALUE))
237                 {
238                     if (forbiddenAttributes == null)
239                     {
240                         forbiddenAttributes = new HashSet JavaDoc();
241                     }
242                     Attribute att = oldEntry.get(attribute);
243                     newEntry.put(att);
244                     forbiddenAttributes.add(att); // nb. it is possible to add the same att twice if it
245
// has two long values. We don't care.
246
}
247                 else
248                 {
249                     
250                     if (newEntry.get(attribute) != null) // append to existing attributes
251
{
252                         if (dataLength != 0) // don't add empty attribute values to existing attributes
253
{
254                             Attribute att = newEntry.get(attribute);
255                             
256                             // check that this isn't an attribute containing a
257
// very long string.
258
if (forbiddenAttributes == null || forbiddenAttributes.contains(att) == false)
259                                 att.add(val);
260                         }
261                     }
262                     else
263                     {
264                         // nb. no need to test forbidden Attributes here, as this is the first time
265
// we've met this particular attribute.
266

267                         if (dataLength != 0)
268                             newEntry.put(new DXAttribute(attribute,val)); // create new attributes
269
else
270                             newEntry.put(new DXAttribute(attribute)); // create new empty attribute
271
}
272                 }
273                                     
274                 start = end + 1;
275             }
276         }
277         catch (Exception JavaDoc e)
278         {
279             CBUtility.error(templateDisplay, "Unable to submit form due\nto a problem with the query url.", new Exception JavaDoc("Parser error in MyHTMLEditorKit - badly formed query url: " + data + "\n " + e.toString()));
280             return null; // exit
281
}
282
283         return newEntry;
284     }
285 }
286
287
288 public class MyHTMLEditorKit extends HTMLEditorKit
289 {
290     private final ViewFactory newDefaultFactory;
291
292     public MyHTMLEditorKit(HTMLTemplateDisplay display)
293     {
294         super();
295         newDefaultFactory = new MyHTMLFactory(display);
296     }
297
298     public ViewFactory getViewFactory()
299     {
300         return newDefaultFactory;
301     }
302
303     public static class MyHTMLFactory extends HTMLEditorKit.HTMLFactory
304     {
305         private final HTMLTemplateDisplay templateDisplay;
306     
307         public MyHTMLFactory(HTMLTemplateDisplay display)
308         {
309             super();
310             templateDisplay = display;
311         }
312     
313         /** overload the create method to serve up our own version of FormView
314          * and ImageView...
315          */

316         public View create(Element elem)
317         {
318             View v = super.create(elem);
319             if (v instanceof FormView)
320                 v = new MyFormView(elem, templateDisplay);
321             return v;
322         }
323     }
324   
325 }
Popular Tags