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