1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.jndi;
18  
19  
20  import java.util.Hashtable;
21  
22  import javax.naming.Context;
23  import javax.naming.Name;
24  import javax.naming.NamingException;
25  import javax.naming.directory.Attribute;
26  import javax.naming.directory.Attributes;
27  import javax.naming.directory.BasicAttribute;
28  import javax.naming.directory.BasicAttributes;
29  import javax.naming.directory.SchemaViolationException;
30  import javax.naming.spi.DirObjectFactory;
31  import javax.naming.spi.DirStateFactory;
32  
33  import org.apache.ldap.server.AbstractAdminTestCase;
34  
35  
36  /***
37   * Tests to make sure that object and state factories work.
38   *
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   * @version $Rev: 264732 $
41   */
42  public class ObjStateFactoryTest extends AbstractAdminTestCase
43  {
44      public void testObjectFactory() throws NamingException
45      {
46          super.sysRoot.addToEnvironment( Context.OBJECT_FACTORIES, PersonObjectFactory.class.getName() );
47  
48          Object obj = super.sysRoot.lookup( "uid=akarasulu, ou=users" );
49  
50          Attributes attrs = super.sysRoot.getAttributes( "uid=akarasulu, ou=users" );
51  
52          assertEquals( Person.class, obj.getClass() );
53  
54          Person me = ( Person ) obj;
55  
56          assertEquals( attrs.get( "sn" ).get(), me.getLastname() );
57  
58          assertEquals( attrs.get( "cn" ).get(), me.getCn() );
59  
60          assertEquals( attrs.get( "userPassword" ).get(), me.getPassword() );
61  
62          assertEquals( attrs.get( "telephonenumber" ).get(), me.getTelephoneNumber() );
63  
64          assertNull( me.getSeealso() );
65  
66          assertNull( me.getDescription() );
67      }
68  
69  
70      public void testStateFactory() throws NamingException
71      {
72          super.sysRoot.addToEnvironment( Context.STATE_FACTORIES, PersonStateFactory.class.getName() );
73  
74          Person p = new Person( "Rodriguez", "Mr. Kerberos", "noices", "555-1212", "erodriguez", "committer" );
75  
76          super.sysRoot.bind( "uid=erodriguez, ou=users", p );
77  
78          Attributes attrs = super.sysRoot.getAttributes( "uid=erodriguez, ou=users" );
79  
80          assertEquals( "Rodriguez", attrs.get( "sn" ).get() );
81  
82          assertEquals( "Mr. Kerberos", attrs.get( "cn" ).get() );
83  
84          assertEquals( "noices", attrs.get( "userPassword" ).get() );
85  
86          assertEquals( "555-1212", attrs.get( "telephonenumber" ).get() );
87  
88          assertEquals( "erodriguez", attrs.get( "seealso" ).get() );
89  
90          assertEquals( "committer", attrs.get( "description" ).get() );
91  
92      }
93  
94  
95      public static class PersonStateFactory implements DirStateFactory
96      {
97          public Result getStateToBind( Object obj, Name name, Context nameCtx, Hashtable environment, Attributes inAttrs ) throws NamingException
98          {
99              // Only interested in Person objects
100             if ( obj instanceof Person )
101             {
102 
103                 Attributes outAttrs;
104 
105                 if ( inAttrs == null )
106                 {
107                     outAttrs = new BasicAttributes(true);
108                 }
109                 else
110                 {
111                     outAttrs = ( Attributes ) inAttrs.clone();
112                 }
113 
114                 // Set up object class
115                 if ( outAttrs.get( "objectclass" ) == null )
116                 {
117                     BasicAttribute oc = new BasicAttribute( "objectclass", "person" );
118 
119                     oc.add( "top" );
120 
121                     outAttrs.put( oc );
122                 }
123 
124                 Person per = ( Person ) obj;
125 
126                 // mandatory attributes
127                 if ( per.getLastname() != null )
128                 {
129                     outAttrs.put( "sn", per.getLastname() );
130                 }
131                 else
132                 {
133                     throw new SchemaViolationException( "Person must have surname" );
134                 }
135 
136                 if ( per.getCn() != null )
137                 {
138                     outAttrs.put( "cn", per.getCn() );
139                 }
140                 else
141                 {
142                     throw new SchemaViolationException( "Person must have common name" );
143                 }
144 
145                 // optional attributes
146                 if ( per.getPassword() != null )
147                 {
148                     outAttrs.put( "userPassword", per.getPassword() );
149                 }
150                 if ( per.getTelephoneNumber() != null )
151                 {
152                     outAttrs.put( "telephoneNumber", per.getTelephoneNumber() );
153                 }
154                 if ( per.getSeealso() != null )
155                 {
156                     outAttrs.put( "seeAlso", per.getSeealso() );
157                 }
158                 if ( per.getDescription() != null )
159                 {
160                     outAttrs.put( "description", per.getDescription() );
161                 }
162 
163                 return new DirStateFactory.Result( null, outAttrs );
164             }
165 
166             return null;
167         }
168 
169 
170         public Object getStateToBind( Object obj, Name name, Context nameCtx, Hashtable environment ) throws NamingException
171         {
172             throw new UnsupportedOperationException( "Please use directory support overload with Attributes argument." );
173         }
174     }
175 
176     public static class PersonObjectFactory implements DirObjectFactory
177     {
178         public Object getObjectInstance( Object obj, Name name, Context nameCtx, Hashtable environment, Attributes attrs ) throws Exception
179         {
180             // Only interested in Attributes with "person" objectclass
181             // System.out.println("object factory: " + attrs);
182             Attribute oc = (attrs != null ? attrs.get("objectclass") : null);
183             if (oc != null && oc.contains("person")) {
184                 Attribute attr;
185             String passwd = null;
186 
187             // Extract the password
188             attr = attrs.get("userPassword");
189             if (attr != null) {
190                 Object pw = attr.get();
191 
192                 if ( pw instanceof String )
193                     passwd = ( String ) pw;
194                 else
195                     passwd = new String((byte[]) pw);
196             }
197                 Person per = new Person(
198                   (String)attrs.get("sn").get(),
199                   (String)attrs.get("cn").get(),
200               passwd,
201                   (attr=attrs.get("telephoneNumber")) != null ? (String)attr.get() : null,
202                   (attr=attrs.get("seealso")) != null ? (String)attr.get() : null,
203                   (attr=attrs.get("description")) != null ? (String)attr.get() : null);
204                 return per;
205             }
206             return null;
207         }
208 
209 
210         public Object getObjectInstance( Object obj, Name name, Context nameCtx, Hashtable environment ) throws Exception
211         {
212             throw new UnsupportedOperationException( "Please use directory support overload with Attributes argument." );
213         }
214     }
215 
216 
217     public static class Person
218     {
219         private String sn, cn, pwd, tele, seealso, desc;
220 
221         public Person( String sn, String cn, String pwd, String tele, String seealso, String desc )
222         {
223             this.sn = sn;
224             this.cn = cn;
225             this.pwd = pwd;
226             this.tele = tele;
227             this.seealso = seealso;
228             this.desc = desc;
229         }
230 
231 
232         public String getLastname()
233         {
234             return sn;
235         }
236 
237 
238         public String getCn()
239         {
240             return cn;
241         }
242 
243 
244         public String getPassword()
245         {
246             return pwd;
247         }
248 
249 
250         public String getTelephoneNumber()
251         {
252             return tele;
253         }
254 
255 
256         public String getSeealso()
257         {
258             return seealso;
259         }
260 
261 
262         public String getDescription()
263         {
264             return desc;
265         }
266     }
267 }