1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * Demonstrate Java object storage and retrieval using an LDAP directory.
26 * The Fruit object and its associated object factory is supplied by a
27 * third-party module. The Fruit object implements javax.naming.Referenceable.
28 */
29
30package test;
31
32import java.net.*;
33import java.util.*;
34import javax.naming.*;
35import javax.naming.directory.*;
36
37import org.example.fruit.Fruit;
38
39public class StoreFruit {
40
41    // LDAP capture file
42    private static final String LDAP_CAPTURE_FILE =
43        System.getProperty("test.src") + "/src/test/test/StoreFruit.ldap";
44    // LDAPServer socket
45    private static ServerSocket serverSocket;
46
47    public static void main(String[] args) throws Exception {
48
49        /*
50         * Process arguments
51         */
52
53        int argc = args.length;
54        if ((argc < 1) ||
55            ((argc == 1) && (args[0].equalsIgnoreCase("-help")))) {
56
57            System.err.println("\nUsage:   StoreFruit <ldapurl>\n");
58            System.err.println("        <ldapurl> is the LDAP URL of the parent entry\n");
59            System.err.println("example:");
60            System.err.println("        java StoreFruit ldap://oasis/o=airius.com");
61    return;
62        }
63
64        /*
65         * Launch the LDAP server with the StoreFruit.ldap capture file
66         */
67
68        serverSocket = new ServerSocket(0);
69        new Thread(new Runnable() {
70            @Override
71            public void run() {
72                try {
73                    new LDAPServer(serverSocket, LDAP_CAPTURE_FILE);
74               } catch (Exception e) {
75                   System.out.println("ERROR: unable to launch LDAP server");
76                   e.printStackTrace();
77               }
78            }
79        }).start();
80
81        /*
82         * Store fruit objects in the LDAP directory
83         */
84
85        Hashtable<String,Object> env = new Hashtable<>();
86        env.put(Context.INITIAL_CONTEXT_FACTORY,
87    "com.sun.jndi.ldap.LdapCtxFactory");
88        URI ldapUri = new URI(args[0]);
89        if (ldapUri.getPort() == -1) {
90            ldapUri = new URI(ldapUri.getScheme(), null, ldapUri.getHost(),
91                serverSocket.getLocalPort(), ldapUri.getPath(), null, null);
92        }
93        env.put(Context.PROVIDER_URL, ldapUri.toString());
94        if (args[args.length - 1].equalsIgnoreCase("-trace")) {
95            env.put("com.sun.jndi.ldap.trace.ber", System.out);
96        }
97
98        System.out.println("StoreFruit: connecting to " + ldapUri);
99        DirContext ctx = new InitialDirContext(env);
100        Fruit fruit = null;
101        String dn = "cn=myfruit";
102        String dn2 = "cn=myapple";
103
104        try {
105            fruit = new Fruit("orange");
106            ctx.bind(dn, fruit);
107            System.out.println("StoreFruit: created entry '" + dn + "'");
108        } catch (NameAlreadyBoundException e) {
109            System.err.println("StoreFruit: entry '" + dn +
110                "' already exists");
111            cleanup(ctx, (String)null);
112            return;
113        }
114
115        try {
116            ctx.bind(dn2, new Fruit("apple"));
117            System.out.println("StoreFruit: created entry '" + dn2 + "'");
118        } catch (NameAlreadyBoundException e) {
119            System.err.println("StoreFruit: entry '" + dn2 +
120                "' already exists");
121            cleanup(ctx, dn);
122            return;
123        }
124
125        /*
126         * Retrieve fruit objects from the LDAP directory
127         */
128
129        try {
130            Fruit fruit2 = (Fruit) ctx.lookup(dn);
131            System.out.println("StoreFruit: retrieved object: " + fruit2);
132        } catch (NamingException e) {
133            System.err.println("StoreFruit: error retrieving entry '" +
134                dn + "' " + e);
135            e.printStackTrace();
136            cleanup(ctx, dn, dn2);
137            return;
138        }
139
140        try {
141            Fruit fruit3 = (Fruit) ctx.lookup(dn2);
142            System.out.println("StoreFruit: retrieved object: " + fruit3);
143        } catch (NamingException e) {
144            System.err.println("StoreFruit: error retrieving entry '" +
145                dn2 + "' " + e);
146            e.printStackTrace();
147            cleanup(ctx, dn, dn2);
148            return;
149        }
150
151        cleanup(ctx, dn, dn2);
152    }
153
154    /*
155     * Remove objects from the LDAP directory
156     */
157    private static void cleanup(DirContext ctx, String... dns)
158        throws NamingException {
159
160        for (String dn : dns) {
161            try {
162                ctx.destroySubcontext(dn);
163                System.out.println("StoreFruit: removed entry '" + dn + "'");
164            } catch (NamingException e) {
165                System.err.println("StoreFruit: error removing entry '" + dn +
166                    "' " + e);
167            }
168        }
169        ctx.close();
170    }
171}
172