View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  
46  package org.exolab.castor.dsml.jndi;
47  
48  import javax.naming.NamingException;
49  import javax.naming.NamingEnumeration;
50  import javax.naming.directory.Attribute;
51  import javax.naming.directory.Attributes;
52  import javax.naming.directory.SearchResult;
53  import org.xml.sax.DocumentHandler;
54  import org.xml.sax.SAXException;
55  import org.xml.sax.helpers.AttributeListImpl;
56  import org.castor.core.util.Base64Encoder;
57  import org.exolab.castor.dsml.XML;
58  import org.exolab.castor.dsml.Producer;
59  import org.exolab.castor.dsml.ImportExportException;
60  
61  /**
62   * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
63   * @version $Revision$ $Date: 2005-08-05 13:58:36 -0600 (Fri, 05 Aug 2005) $
64   */
65  public class JNDIProducer extends Producer {
66      public JNDIProducer(final DocumentHandler docHandler, final boolean namespace) {
67          super(docHandler, namespace);
68      }
69  
70      public void produce(final String name, final Attributes attrs)
71      throws SAXException, NamingException {
72          AttributeListImpl attrList;
73          Attribute attr;
74  
75          leaveSchema();
76          enterDirectory();
77  
78          // dsml:entry dn
79          attrList = new AttributeListImpl();
80          attrList.addAttribute(XML.Entries.Attributes.DN, "CDATA", name);
81          // dsml:entry
82          _docHandler.startElement(prefix(XML.Entries.Elements.ENTRY), attrList);
83  
84          if (attrs != null) {
85              attr = attrs.get("objectclass");
86              if (attr != null) {
87                  // dsml:objectclass
88                  attrList = new AttributeListImpl();
89                  _docHandler.startElement(prefix(XML.Entries.Elements.OBJECT_CLASS), attrList);
90                  NamingEnumeration<?> values = attr.getAll();
91                  while (values.hasMore()) {
92                      char[] chars;
93  
94                      // dsml:oc-value
95                      Object value = values.next();
96                      if (value != null) {
97                          chars = value.toString().toCharArray();
98                      } else {
99                          chars = new char[0];
100                     }
101                     attrList = new AttributeListImpl();
102                     _docHandler.startElement(prefix(XML.Entries.Elements.OBJECT_CLASS_VALUE),
103                             attrList);
104                     _docHandler.characters(chars, 0, chars.length);
105                     _docHandler.endElement(prefix(XML.Entries.Elements.OBJECT_CLASS_VALUE));
106                 }
107                 _docHandler.endElement(prefix(XML.Entries.Elements.OBJECT_CLASS));
108             }
109 
110             NamingEnumeration<? extends Attribute> enumeration = attrs.getAll();
111             while (enumeration.hasMore()) {
112                 // dsml:attr
113                 attr = enumeration.next();
114                 if (attr.getID().equals("objectclass")) {
115                     continue;
116                 }
117                 attrList = new AttributeListImpl();
118                 attrList.addAttribute(XML.Entries.Attributes.NAME, "CDATA", attr.getID());
119                 _docHandler.startElement(prefix(XML.Entries.Elements.ATTRIBUTE), attrList);
120 
121                 NamingEnumeration<?> values = attr.getAll();
122                 while (values.hasMore()) {
123                     char[] chars = null;
124                     byte[] bytes = null;
125 
126                     attrList = new AttributeListImpl();
127 
128                     // dsml:value
129                     Object value = values.next();
130                     if (value == null) {
131                         chars = new char[ 0 ];
132                     } else if (value instanceof String) {
133                         chars = ((String) value).toCharArray();
134                     } else if (value instanceof byte[]) {
135                         bytes = (byte[]) value;
136                     } else {
137                         chars = value.toString().toCharArray();
138                     }
139                     if (chars != null) {
140                         boolean encode = false;
141                         boolean wchar = false;
142                         int i = 0;
143                         while (i < chars.length && !wchar) {
144                             char c = chars[i++];
145                             if (c >= '\u0100') {
146                                 encode = true;
147                                 wchar = true;
148                             } else if (c >= '\u0080' || (c < ' ' && c != '\n' && c != '\t')) {
149                                 encode = true;
150                             }
151                         }
152                         if (encode) {
153                             if (wchar) {
154                                 bytes = new byte[chars.length << 1];
155                                 int j = 0;
156                                 // big endian
157                                 for (i = 0; i < chars.length; i++) {
158                                     bytes[j++] = (byte) (chars[i] >> 8);
159                                     bytes[j++] = (byte) (0xff & chars[i]);
160                                 }
161                             } else {
162                                 bytes = new byte[chars.length];
163                                 for (i = 0; i < chars.length; i++) {
164                                     bytes[i] = (byte) chars[i];
165                                 }
166                             }
167                         }
168                     }
169 
170                     if (bytes != null) {
171                         chars = Base64Encoder.encode(bytes);
172                         attrList.addAttribute(XML.Entries.Attributes.ENCODING, "NMTOKEN",
173                                 XML.Entries.Attributes.Encodings.BASE64);
174                     }
175                     _docHandler.startElement(prefix(XML.Entries.Elements.VALUE), attrList);
176                     _docHandler.characters(chars, 0, chars.length);
177                     _docHandler.endElement(prefix(XML.Entries.Elements.VALUE));
178                 }
179                 _docHandler.endElement(prefix(XML.Entries.Elements.ATTRIBUTE));
180             }
181         }
182         _docHandler.endElement(prefix(XML.Entries.Elements.ENTRY));
183     }
184 
185     public void produce(final SearchResult result) throws SAXException {
186         try {
187             produce(result.getName(), result.getAttributes());
188         } catch (NamingException except) {
189             throw new SAXException(except.toString());
190         }
191     }
192 
193     public void produce(final NamingEnumeration<SearchResult> results)
194     throws ImportExportException, SAXException {
195         try {
196             while (results.hasMore()) {
197                 SearchResult result = results.next();
198                 produce(result.getName(), result.getAttributes());
199             }
200         } catch (NamingException except) {
201             throw new ImportExportException(except);
202         }
203     }
204 }